Author: vdedik
Date: 2012-08-15 10:28:58 -0400 (Wed, 15 Aug 2012)
New Revision: 15048
Added:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/display.xhtml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/edit.xhtml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/bookingExp.html
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/confirmExp.html
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/introExp.html
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/loginExp.html
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/mainExp.html
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/registerExp.html
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/workspaceExp.html
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/hotelview.xhtml
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/groovy/org/jboss/seam/example/groovy/action/BookingListAction.groovy
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/groovy/org/jboss/seam/example/groovy/action/HotelBookingAction.groovy
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/components.xml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/faces-config.xml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/pages.xml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/web.xml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/book.xhtml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/confirm.xhtml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/conversations.xhtml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/css/screen.css
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/home.xhtml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/hotel.xhtml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/main.xhtml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/password.xhtml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/register.xhtml
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/template.xhtml
Log:
groovybooking updated to more reflect current booking
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/groovy/org/jboss/seam/example/groovy/action/BookingListAction.groovy
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/groovy/org/jboss/seam/example/groovy/action/BookingListAction.groovy 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/groovy/org/jboss/seam/example/groovy/action/BookingListAction.groovy 2012-08-15
14:28:58 UTC (rev 15048)
@@ -9,6 +9,7 @@
import org.jboss.seam.annotations.Logger
import org.jboss.seam.annotations.Name
import org.jboss.seam.annotations.Scope
+import org.jboss.seam.annotations.Observer;
import org.jboss.seam.annotations.datamodel.DataModel
import org.jboss.seam.annotations.datamodel.DataModelSelection
import org.jboss.seam.faces.FacesMessages
@@ -37,6 +38,7 @@
Log log
@Factory
+ @Observer("bookingConfirmed")
public void getBookings()
{
bookings = em.createQuery('''
@@ -56,4 +58,9 @@
FacesMessages.instance().add("Booking cancelled for confirmation number
#0", booking.getId())
}
+ public Booking getBooking()
+ {
+ return booking
+ }
+
}
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/groovy/org/jboss/seam/example/groovy/action/HotelBookingAction.groovy
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/groovy/org/jboss/seam/example/groovy/action/HotelBookingAction.groovy 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/groovy/org/jboss/seam/example/groovy/action/HotelBookingAction.groovy 2012-08-15
14:28:58 UTC (rev 15048)
@@ -80,19 +80,13 @@
}
}
- @Out (required=false, scope=ScopeType.SESSION)
- List <Booking> bookings
-
@End
void confirm()
{
em.persist(booking)
facesMessages.add "Thank you, #{user.name}, your confimation number for
#{hotel.name} is #{booking.id}", new Object[0]
log.info("New booking: #{booking.id} for #{user.username}")
- // events.raiseTransactionSuccessEvent("bookingConfirmed")
-
- // force refresh in main.xhtml
- bookings = null
+ events.raiseTransactionSuccessEvent("bookingConfirmed")
}
@End
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/components.xml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/components.xml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/components.xml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -2,14 +2,12 @@
<components
xmlns="http://jboss.org/schema/seam/components"
xmlns:core="http://jboss.org/schema/seam/core"
xmlns:persistence="http://jboss.org/schema/seam/persistence"
-
xmlns:drools="http://jboss.org/schema/seam/drools"
xmlns:security="http://jboss.org/schema/seam/security"
xmlns:mail="http://jboss.org/schema/seam/mail"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://jboss.org/schema/seam/core
http://jboss.org/schema/seam/core-2.3.xsd
-
http://jboss.org/schema/seam/persistence
http://jboss.org/schema/seam/persistence-2.3.xsd
-
http://jboss.org/schema/seam/drools
http://jboss.org/schema/seam/drools-2.3.xsd
+
http://jboss.org/schema/seam/persistence
http://jboss.org/schema/seam/persistence-2.3.xsd
http://jboss.org/schema/seam/security
http://jboss.org/schema/seam/security-2.3.xsd
http://jboss.org/schema/seam/mail
http://jboss.org/schema/seam/mail-2.3.xsd
http://jboss.org/schema/seam/components
http://jboss.org/schema/seam/components-2.3.xsd">
@@ -31,13 +29,6 @@
<security:identity authenticate-method="#{authenticator.authenticate}"
remember-me="true"/>
-
- <event type="org.jboss.seam.security.notLoggedIn">
- <action execute="#{redirect.captureCurrentView}"/>
- </event>
- <event type="org.jboss.seam.security.loginSuccessful">
- <action execute="#{redirect.returnToCapturedView}"/>
- </event>
<mail:mail-session host="localhost" port="2525"
username="test" password="test" />
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/faces-config.xml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/faces-config.xml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/faces-config.xml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -3,4 +3,5 @@
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd">
+
</faces-config>
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/jboss-deployment-structure.xml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/jboss-deployment-structure.xml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -1,12 +1,12 @@
-<jboss-deployment-structure>
+<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
<deployment>
<dependencies>
- <!-- <module name="org.apache.log4j" />-->
- <module name="org.dom4j" />
-<!-- <module name="org.apache.commons.logging" />
- <module name="org.apache.commons.collections" />
- <module name="javax.faces.api"/>
- <module name="com.sun.jsf-impl"/>-->
+ <module name="org.apache.log4j" export="true"/>
+ <module name="org.dom4j" export="true"/>
+ <module name="org.apache.commons.logging"
export="true"/>
+ <module name="org.apache.commons.collections"
export="true"/>
+ <module name="javax.faces.api" export="true"/>
+ <module name="com.sun.jsf-impl" export="true"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/pages.xml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/pages.xml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/pages.xml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -8,8 +8,7 @@
<page view-id="/register.xhtml">
- <action if="#{validation.failed}"
- execute="#{register.invalid}"/>
+ <action if="#{validation.failed}"
execute="#{register.invalid}"/>
<navigation>
<rule if="#{register.registered}">
@@ -19,12 +18,15 @@
</page>
- <page view-id="/home.xhtml">
+ <page view-id="/home.xhtml"
action="#{identity.isLoggedIn}">
- <navigation>
- <rule if="#{identity.loggedIn}">
+ <navigation from-action="#{identity.isLoggedIn}">
+ <rule if-outcome="true">
<redirect view-id="/main.xhtml"/>
</rule>
+ <rule if-outcome="false">
+ <render view-id="/home.xhtml"/>
+ </rule>
</navigation>
</page>
@@ -33,7 +35,7 @@
login-required="true">
<navigation>
- <rule if="#{changePassword.changed}">
+ <rule if="#{identity.loggedIn and changePassword.changed}">
<redirect view-id="/main.xhtml"/>
</rule>
</navigation>
@@ -47,10 +49,15 @@
<redirect view-id="/hotel.xhtml"/>
</navigation>
+ <navigation from-action="#{bookingList.cancel}">
+ <redirect/>
+ </navigation>
+
</page>
- <page view-id="/hotel.xhtml"
- conversation-required="true">
+ <page view-id="/hotel.xhtml"
+ conversation-required="true"
+ login-required="true">
<description>View hotel: #{hotel.name}</description>
@@ -60,8 +67,9 @@
</page>
- <page view-id="/book.xhtml"
- conversation-required="true">
+ <page view-id="/book.xhtml"
+ conversation-required="true"
+ login-required="true">
<description>Book hotel: #{hotel.name}</description>
@@ -73,8 +81,9 @@
</page>
- <page view-id="/confirm.xhtml"
- conversation-required="true">
+ <page view-id="/confirm.xhtml"
+ conversation-required="true"
+ login-required="true">
<description>Confirm booking: #{booking.description}</description>
@@ -85,7 +94,6 @@
</page>
<page view-id="*">
-
<navigation from-action="#{identity.logout}">
<redirect view-id="/home.xhtml"/>
</navigation>
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/web.xml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/web.xml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/WEB-INF/web.xml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -1,74 +1,73 @@
-<?xml version="1.0" ?>
-<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="3.0"
+
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
- version="3.0">
-
- <context-param>
- <param-name>org.richfaces.SKIN</param-name>
- <param-value>blueSky</param-value>
- </context-param>
-
+
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+
+ <display-name>Seam Booking Example</display-name>
+
<!-- Seam -->
-
+
<listener>
<listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
</listener>
-
- <filter>
- <filter-name>Seam Filter</filter-name>
- <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>Seam Filter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
<servlet>
<servlet-name>Seam Resource Servlet</servlet-name>
<servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
</servlet>
-
+
<servlet-mapping>
<servlet-name>Seam Resource Servlet</servlet-name>
<url-pattern>/seam/resource/*</url-pattern>
</servlet-mapping>
-
- <!-- Facelets development mode (disable in production) -->
-
- <context-param>
- <param-name>facelets.DEVELOPMENT</param-name>
- <param-value>true</param-value>
- </context-param>
-
+
+ <filter>
+ <filter-name>Seam Filter</filter-name>
+ <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
+ </filter>
+
+ <filter-mapping>
+ <filter-name>Seam Filter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
<!-- JSF -->
-
+
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
+ <context-param>
+ <param-name>org.richfaces.enableControlSkinning</param-name>
+ <param-value>false</param-value>
+ </context-param>
+
+ <!-- <context-param> -->
+ <!--
<param-name>javax.faces.DISABLE_FACELET_JSF_VIEWHANDLER</param-name> -->
+ <!-- <param-value>true</param-value> -->
+ <!-- </context-param> -->
+
+ <!-- <context-param> -->
+ <!-- <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
-->
+ <!--
<param-value>com.sun.facelets.FaceletViewHandler</param-value> -->
+ <!-- </context-param> -->
+
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
-
+
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.seam</url-pattern>
</servlet-mapping>
-
- <security-constraint>
- <display-name>Restrict raw XHTML Documents</display-name>
- <web-resource-collection>
- <web-resource-name>XHTML</web-resource-name>
- <url-pattern>*.xhtml</url-pattern>
- </web-resource-collection>
- <auth-constraint>
- <role-name>NONE</role-name>
- </auth-constraint>
- </security-constraint>
-
+
+ <session-config>
+ <session-timeout>10</session-timeout>
+ </session-config>
+
</web-app>
+
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/book.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/book.xhtml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/book.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -14,156 +14,89 @@
<h1>Book Hotel</h1>
</div>
<div class="section">
+ <div class="entry errors">
+ <s:message id="messages" globalOnly="true"/>
+ </div>
+
+ <ui:include src="hotelview.xhtml"/>
+
+ <div style="clear:both"/>
+
<h:form id="booking">
<fieldset>
- <div class="entry">
- <div class="label">Name:</div>
- <div class="output">#{hotel.name}</div>
- </div>
- <div class="entry">
- <div class="label">Address:</div>
- <div class="output">#{hotel.address}</div>
- </div>
- <div class="entry">
- <div class="label">City, State:</div>
- <div class="output">#{hotel.city}, #{hotel.state}</div>
- </div>
- <div class="entry">
- <div class="label">Zip:</div>
- <div class="output">#{hotel.zip}</div>
- </div>
- <div class="entry">
- <div class="label">Country:</div>
- <div class="output">#{hotel.country}</div>
- </div>
- <div class="entry">
- <div class="label">Nightly rate:</div>
- <div class="output">
- <h:outputText value="#{hotel.price}">
- <f:convertNumber type="currency"
- currencySymbol="$"/>
- </h:outputText>
- </div>
- </div>
-
- <s:validateAll>
-
- <f:facet name="aroundInvalidField">
- <s:span id="Error" styleClass="errors"/>
- </f:facet>
- <f:facet name="afterInvalidField">
- <s:div id="Message" styleClass="errors">
- <s:message/>
- </s:div>
- </f:facet>
-
- <div class="entry">
- <div class="label"><h:outputLabel
for="checkinDate">Check In Date:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="checkinDateDecorate">
- <rich:calendar id="checkinDate"
value="#{booking.checkinDate}" required="true"
datePattern="MM/dd/yyyy" event="onblur"
reRender="checkinDateDecorate" style="width: auto;" />
- </s:decorate>
- </div>
- </div>
- <div class="entry">
- <div class="label"><h:outputLabel
for="checkoutDate">Check Out Date:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="checkoutDateDecorate">
- <rich:calendar id="checkoutDate"
value="#{booking.checkoutDate}" required="true"
datePattern="MM/dd/yyyy" event="onblur"
reRender="checkoutDateDecorate" style="width: auto;" />
- </s:decorate>
- </div>
- </div>
+ <s:decorate id="checkinDateDecorate" template="edit.xhtml">
+ <ui:define name="label">Check In Date:</ui:define>
+ <rich:calendar id="checkinDate" value="#{booking.checkinDate}"
required="true" datePattern="MM/dd/yyyy"
render="checkinDateDecorate" style="width: auto;" />
+ </s:decorate>
+
+ <s:decorate id="checkoutDateDecorate" template="edit.xhtml">
+ <ui:define name="label">Check Out Date:</ui:define>
+ <rich:calendar id="checkoutDate"
value="#{booking.checkoutDate}" required="true"
datePattern="MM/dd/yyyy" render="checkoutDateDecorate"
style="width: auto;"/>
+ </s:decorate>
+
+ <s:decorate id="bedsDecorate" template="edit.xhtml">
+ <ui:define name="label">Room Preference:</ui:define>
+ <h:selectOneMenu id="beds" value="#{booking.beds}">
+ <f:selectItem id="OneKingBed" itemLabel="One king-size bed"
itemValue="1"/>
+ <f:selectItem id="TwoDoubleBeds" itemLabel="Two double beds"
itemValue="2"/>
+ <f:selectItem id="ThreeBeds" itemLabel="Three beds"
itemValue="3"/>
+ </h:selectOneMenu>
+ </s:decorate>
+
+ <s:decorate id="smokingDecorate" template="edit.xhtml">
+ <ui:define name="label">Smoking Preference:</ui:define>
+ <h:selectOneRadio id="smoking" value="#{booking.smoking}"
layout="pageDirection" styleClass="radio">
+ <f:selectItem id="Smoking" itemLabel="Smoking"
itemValue="true"/>
+ <f:selectItem id="NonSmoking" itemLabel="Non Smoking"
itemValue="false"/>
+ </h:selectOneRadio>
+ </s:decorate>
- <div class="entry">
- <div class="label"><h:outputLabel for="beds">Room
Preference:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="bedsDecorate">
- <h:selectOneMenu id="beds" value="#{booking.beds}">
- <f:selectItem itemLabel="One king-size bed"
itemValue="1"/>
- <f:selectItem itemLabel="Two double beds"
itemValue="2"/>
- <f:selectItem itemLabel="Three beds" itemValue="3"/>
- </h:selectOneMenu>
- </s:decorate>
- </div>
- </div>
-
- <div class="entry">
- <div class="label"><h:outputLabel
for="smoking">Smoking Preference:</h:outputLabel></div>
- <div id="radio" class="input">
- <s:decorate id="smokingDecorate">
- <h:selectOneRadio id="smoking" value="#{booking.smoking}"
layout="pageDirection">
- <f:selectItem itemLabel="Smoking" itemValue="true"/>
- <f:selectItem itemLabel="Non Smoking"
itemValue="false"/>
- </h:selectOneRadio>
- </s:decorate>
- </div>
- </div>
-
- <div class="entry">
- <div class="label"><h:outputLabel
for="creditCard">Credit Card #:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="creditCardDecorate">
- <h:inputText id="creditCard" value="#{booking.creditCard}"
required="true">
- <a:ajax event="blur"
render="creditCardDecorate"/>
- </h:inputText>
- </s:decorate>
- </div>
- </div>
-
- <div class="entry">
- <div class="label"><h:outputLabel
for="creditCardName">Credit Card Name:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="creditCardNameDecorate">
- <h:inputText id="creditCardName"
value="#{booking.creditCardName}" required="true">
- <a:ajax event="blur"
render="creditCardNameDecorate"/>
- </h:inputText>
- </s:decorate>
- </div>
- </div>
-
- <div class="entry">
- <div class="label"><h:outputLabel
for="creditCardExpiryMonth">Credit Card
Expiry:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="creditCardExpiryDecorate">
- <h:selectOneMenu id="creditCardExpiryMonth"
value="#{booking.creditCardExpiryMonth}">
- <f:selectItem itemLabel="Jan" itemValue="1"/>
- <f:selectItem itemLabel="Feb" itemValue="2"/>
- <f:selectItem itemLabel="Mar" itemValue="3"/>
- <f:selectItem itemLabel="Apr" itemValue="4"/>
- <f:selectItem itemLabel="May" itemValue="5"/>
- <f:selectItem itemLabel="Jun" itemValue="6"/>
- <f:selectItem itemLabel="Jul" itemValue="7"/>
- <f:selectItem itemLabel="Aug" itemValue="8"/>
- <f:selectItem itemLabel="Sep" itemValue="9"/>
- <f:selectItem itemLabel="Oct" itemValue="10"/>
- <f:selectItem itemLabel="Nov" itemValue="11"/>
- <f:selectItem itemLabel="Dec" itemValue="12"/>
- </h:selectOneMenu>
- <h:selectOneMenu id="creditCardExpiryYear"
value="#{booking.creditCardExpiryYear}">
- <f:selectItem itemLabel="2005" itemValue="2005"/>
- <f:selectItem itemLabel="2006" itemValue="2006"/>
- <f:selectItem itemLabel="2007" itemValue="2007"/>
- <f:selectItem itemLabel="2008" itemValue="2008"/>
- <f:selectItem itemLabel="2009" itemValue="2009"/>
- </h:selectOneMenu>
- </s:decorate>
- </div>
- </div>
-
- </s:validateAll>
+ <s:decorate id="creditCardDecorate" template="edit.xhtml">
+ <ui:define name="label">Credit Card #:</ui:define>
+ <h:inputText id="creditCard" value="#{booking.creditCard}"
required="true">
+ <a:ajax event="blur" render="creditCardDecorate"/>
+ </h:inputText>
+ </s:decorate>
+
+ <s:decorate id="creditCardNameDecorate"
template="edit.xhtml">
+ <ui:define name="label">Credit Card Name:</ui:define>
+ <h:inputText id="creditCardName"
value="#{booking.creditCardName}" required="true">
+ <a:ajax event="blur" render="creditCardNameDecorate"/>
+ </h:inputText>
+ </s:decorate>
+
+ <s:decorate id="creditCardExpiryDecorate"
template="edit.xhtml">
+ <ui:define name="label">Credit Card Expiry:</ui:define>
+ <h:selectOneMenu id="creditCardExpiryMonth"
value="#{booking.creditCardExpiryMonth}">
+ <f:selectItem id="Jan" itemLabel="Jan"
itemValue="1"/>
+ <f:selectItem id="Feb" itemLabel="Feb"
itemValue="2"/>
+ <f:selectItem id="Mar" itemLabel="Mar"
itemValue="3"/>
+ <f:selectItem id="Apr" itemLabel="Apr"
itemValue="4"/>
+ <f:selectItem id="May" itemLabel="May"
itemValue="5"/>
+ <f:selectItem id="Jun" itemLabel="Jun"
itemValue="6"/>
+ <f:selectItem id="Jul" itemLabel="Jul"
itemValue="7"/>
+ <f:selectItem id="Aug" itemLabel="Aug"
itemValue="8"/>
+ <f:selectItem id="Sep" itemLabel="Sep"
itemValue="9"/>
+ <f:selectItem id="Oct" itemLabel="Oct"
itemValue="10"/>
+ <f:selectItem id="Nov" itemLabel="Nov"
itemValue="11"/>
+ <f:selectItem id="Dec" itemLabel="Dec"
itemValue="12"/>
+ </h:selectOneMenu>
+ <h:selectOneMenu id="creditCardExpiryYear"
value="#{booking.creditCardExpiryYear}">
+ <f:selectItem id="Year2005" itemLabel="2005"
itemValue="2005"/>
+ <f:selectItem id="Year2006" itemLabel="2006"
itemValue="2006"/>
+ <f:selectItem id="Year2007" itemLabel="2007"
itemValue="2007"/>
+ <f:selectItem id="Year2008" itemLabel="2008"
itemValue="2008"/>
+ <f:selectItem id="Year2009" itemLabel="2009"
itemValue="2009"/>
+ </h:selectOneMenu>
+ </s:decorate>
- <div class="entry errors">
- <h:messages globalOnly="true"/>
+ <div class="buttonBox">
+ <h:commandButton id="proceed" value="Proceed"
action="#{hotelBooking.setBookingDetails}"/>
+  
+ <s:button id="cancel" value="Cancel"
action="#{hotelBooking.cancel}"/>
</div>
- <div class="entry">
- <div class="label"> </div>
- <div class="input">
- <h:commandButton id="proceed" value="Proceed"
action="#{hotelBooking.setBookingDetails}"/> 
- <s:button id="cancel" value="Cancel"
action="#{hotelBooking.cancel}"/>
- </div>
- </div>
</fieldset>
</h:form>
</div>
@@ -171,6 +104,19 @@
<!-- sidebar -->
<ui:define name="sidebar">
+
+<h1>Workspace management</h1>
+<p>
+ As you can see, Seam makes it easy to work in multiple windows or multiple browser
+ tabs. But you can even switch between multiple tasks inside a single browser tab!
+ The "Workspaces" section showcases this advanced feature.
+</p>
+<p>
+ <a href="#"
onclick="window.open('exp/workspaceExp.html','exp','width=752,height=500,scrollbars=yes');">
+ How does the workspace list work?
+ </a>
+</p>
+
</ui:define>
</ui:composition>
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/confirm.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/confirm.xhtml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/confirm.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -8,68 +8,67 @@
<!-- content -->
<ui:define name="content">
+
<div class="section">
<h1>Confirm Hotel Booking</h1>
</div>
+
<div class="section">
- <h:form id="confirm">
- <fieldset>
- <div class="entry">
- <div class="label">Name:</div>
- <div class="output">#{hotel.name}</div>
- </div>
- <div class="entry">
- <div class="label">Address:</div>
- <div class="output">#{hotel.address}</div>
- </div>
- <div class="entry">
- <div class="label">City, State:</div>
- <div class="output">#{hotel.city}, #{hotel.state}</div>
- </div>
- <div class="entry">
- <div class="label">Zip:</div>
- <div class="output">#{hotel.zip}</div>
- </div>
- <div class="entry">
- <div class="label">Country:</div>
- <div class="output">#{hotel.country}</div>
- </div>
- <div class="entry">
- <div class="label">Total payment:</div>
- <div class="output">
- <h:outputText value="#{booking.total}">
- <f:convertNumber type="currency"
- currencySymbol="$"/>
- </h:outputText>
- </div>
- </div>
- <div class="entry">
- <div class="label">Check In Date:</div>
- <div class="output"><h:outputText
value="#{booking.checkinDate}"/></div>
- </div>
- <div class="entry">
- <div class="label">Check Out Date:</div>
- <div class="output"><h:outputText
value="#{booking.checkoutDate}"/></div>
- </div>
- <div class="entry">
- <div class="label">Credit Card #:</div>
- <div class="output">#{booking.creditCard}</div>
- </div>
- <div class="entry">
- <div class="label"> </div>
- <div class="input">
- <h:commandButton id="confirm" value="Confirm"
action="#{hotelBooking.confirm}"/> 
- <s:button id="revise" value="Revise"
view="/book.xhtml"/> 
- <h:commandButton id="cancel" value="Cancel"
action="#{hotelBooking.cancel}"/>
- </div>
- </div>
- </fieldset>
- </h:form>
+
+ <ui:include src="hotelview.xhtml"/>
+
+ <s:decorate id="DecorateTotalPayment"
template="display.xhtml">
+ <ui:define name="label">Total Payment:</ui:define>
+ <h:outputText id="BookingTotal" value="#{booking.total}">
+ <f:convertNumber type="currency" currencySymbol="$"/>
+ </h:outputText>
+ </s:decorate>
+
+ <s:decorate id="DecorateCheckInDate"
template="display.xhtml">
+ <ui:define name="label">Check In Date:</ui:define>
+ <h:outputText id="BookingCheckinDate"
value="#{booking.checkinDate}"/>
+ </s:decorate>
+
+ <s:decorate id="DecorateCheckoutDate"
template="display.xhtml">
+ <ui:define name="label">Check Out Date:</ui:define>
+ <h:outputText id="BookingCheckoutDate"
value="#{booking.checkoutDate}"/>
+ </s:decorate>
+
+ <s:decorate id="DecorateCreditCard" template="display.xhtml">
+ <ui:define name="label">Credit Card #:</ui:define>
+ #{booking.creditCard}
+ </s:decorate>
+
+ <div class="buttonBox">
+ <h:form id="confirm">
+ <h:commandButton id="confirm" value="Confirm"
action="#{hotelBooking.confirm}"/>
+  
+ <s:button id="revise" value="Revise"
view="/book.xhtml"/>
+  
+ <h:commandButton id="cancel" value="Cancel"
action="#{hotelBooking.cancel}"/>
+ </h:form>
+ </div>
+
</div>
+
</ui:define>
<!-- sidebar -->
<ui:define name="sidebar">
+<h1>Back button navigation</h1>
+<p>
+ When you click "Confirm", the new booking is written to the database, the
+ conversation ends, and state associated with the conversation is automatically
+ destroyed by Seam. After you confirm your booking, try hitting the back button
+ on your web browser and clicking "Confirm" again. Seam makes it easy
implement
+ applications that behave elegantly in response to the back, forward and refresh
+ buttons.
+</p>
+<p>
+ <a href="#"
onclick="window.open('exp/confirmExp.html','exp','width=752,height=500,scrollbars=yes');">
+ What happens when the conversation ends?
+ </a>
+</p>
</ui:define>
</ui:composition>
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/conversations.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/conversations.xhtml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/conversations.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -1,34 +1,38 @@
-<!-- DOCTYPE div PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" -->
-<div
xmlns="http://www.w3.org/1999/xhtml"
+<!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:c="http://java.sun.com/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:s="http://jboss.org/schema/seam/taglib">
-
-<div class="section">
- <h1><h:outputText rendered="#{not empty conversationList}"
value="Workspaces"/></h1>
-</div>
-
-<div class="section">
- <h:form id="ConversationListForm">
- <h:dataTable id="ConversationListDataTable"
value="#{conversationList}" var="entry">
- <h:column id="column1">
- <h:commandLink id="EntryDescriptionLink"
action="#{entry.select}" value="#{entry.description}"/>
-  
- <h:outputText id="CurrentEntry" value="[current]"
rendered="#{entry.current}"/>
- </h:column>
- <h:column id="column2">
- <h:outputText id="EntryStartDateTime"
value="#{entry.startDatetime}">
- <f:convertDateTime type="time"
pattern="hh:mm"/>
- </h:outputText>
- -
- <h:outputText id="EntryLastDateTime"
value="#{entry.lastDatetime}">
- <f:convertDateTime type="time"
pattern="hh:mm"/>
- </h:outputText>
- </h:column>
- </h:dataTable>
- </h:form>
-</div>
-
-</div>
+ <div>
+
+ <div class="section">
+ <h1><h:outputText rendered="#{not empty conversationList}"
value="Workspaces"/></h1>
+ </div>
+
+ <div class="section">
+ <h:form id="ConversationListForm">
+ <h:dataTable id="ConversationListDataTable"
value="#{conversationList}" var="entry">
+ <h:column id="column1">
+ <h:commandLink id="EntryDescriptionLink"
action="#{entry.select}" value="#{entry.description}"/>
+  
+ <h:outputText id="CurrentEntry" value="[current]"
rendered="#{entry.current}"/>
+ </h:column>
+ <h:column id="column2">
+ <h:outputText id="EntryStartDateTime"
value="#{entry.startDatetime}">
+ <!--<s:convertDateTime type="time"
pattern="kk:mm:ss"/>-->
+ <f:convertDateTime type="time"
pattern="kk:mm:ss"/>
+ </h:outputText>
+ -
+ <h:outputText id="EntryLastDateTime"
value="#{entry.lastDatetime}">
+ <!--<s:convertDateTime type="time"
pattern="hh:mm"/>-->
+ <f:convertDateTime type="time"
pattern="kk:mm:ss"/>
+ </h:outputText>
+ </h:column>
+ </h:dataTable>
+ </h:form>
+ </div>
+
+ </div>
+</ui:composition>
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/css/screen.css
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/css/screen.css 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/css/screen.css 2012-08-15
14:28:58 UTC (rev 15048)
@@ -1,6 +1,6 @@
/* Setup defaults since variable in browsers
----------------------------------------------- */
-body, div, dd, dt, dl, img, ul, ol, li, p, h1, h2, h3, h4, h5, form, hr, fieldset {
+body, div, span, dd, dt, dl, img, ul, ol, li, p, h1, h2, h3, h4, h5, form, hr, fieldset
{
margin: 0;
padding: 0;
}
@@ -24,7 +24,7 @@
margin-left: auto;
margin-right: auto;
}
-label {
+.label {
font-weight: bold;
color: #5E5147;
}
@@ -39,7 +39,8 @@
padding: 4px;
margin: 5px 0;
background: #fff url(../img/input.bg.gif) 0 0 repeat-x;
-}ol, ul {
+}
+ol, ul {
margin: 10px 0px 10px 6px;
}
li {
@@ -110,23 +111,27 @@
}
.entry .label {
float: left;
- padding-top: 10px;
padding-right: 5px;
font-weight: bold;
width: 150px;
text-align: right;
}
.entry .output {
- float: left;
- width: 250px;
+ float: right;
+ width: 360px;
padding-top: 10px;
text-align: left;
}
.entry .input {
- float: left;
- width: 250px;
+ float: right;
+ width: 360px;
text-align: left;
}
+.entry .error {
+ float: right;
+ width: 360px;
+ text-align: left;
+}
/* Sidebar
----------------------------------------------- */
.notes {
@@ -146,6 +151,9 @@
.errors div {
text-align: left;
}
+.errors span {
+ text-align: left;
+}
.errors input {
border: 1px solid #600;
}
@@ -155,6 +163,7 @@
.buttonBox {
text-align: center;
padding: 5px 0;
+ clear: both;
}
#sidebar p {
font-size: small;
@@ -228,12 +237,12 @@
float: left;
width: 66%;
}
-#radio table {
+#content table.radio {
border: 0px;
}
#content .input table,
#content .input tbody tr td,
-#radio table tr td {
+#content table.radio tbody tr td {
border: 0px;
border-left: 0px;
border-bottom: 0px;
@@ -269,6 +278,3 @@
#pgHome #content {
margin-top: 183px;
}
-#pgHome #sidebar input[type="submit"] {
- height: 30px;
-}
Added:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/display.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/display.xhtml
(rev 0)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/display.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -0,0 +1,16 @@
+<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
+
xmlns:ui="http://java.sun.com/jsf/facelets"
+
xmlns:h="http://java.sun.com/jsf/html"
+
xmlns:f="http://java.sun.com/jsf/core"
+
xmlns:s="http://jboss.org/schema/seam/taglib">
+
+ <div class="entry">
+ <span class="label">
+ <ui:insert name="label"/>
+ </span>
+ <span class="input">
+ <ui:insert/>
+ </span>
+ </div>
+
+</ui:composition>
\ No newline at end of file
Added:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/edit.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/edit.xhtml
(rev 0)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/edit.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -0,0 +1,21 @@
+<!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:h="http://java.sun.com/jsf/html"
+
xmlns:f="http://java.sun.com/jsf/core"
+
xmlns:s="http://jboss.org/schema/seam/taglib">
+
+ <div class="entry">
+ <s:label id="Label" styleClass="label
#{invalid?'errors':''}">
+ <ui:insert name="label"/>
+ <s:span id="RequiredStyle" styleClass="required"
rendered="#{required}">*</s:span>
+ </s:label>
+ <span class="input #{invalid?'errors':''}">
+ <s:validateAll id="ValidateAll">
+ <ui:insert/>
+ </s:validateAll>
+ </span>
+ <s:message id="message" styleClass="error errors"
globalOnly="true"/>
+ </div>
+
+</ui:composition>
\ No newline at end of file
Added:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/bookingExp.html
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/bookingExp.html
(rev 0)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/bookingExp.html 2012-08-15
14:28:58 UTC (rev 15048)
@@ -0,0 +1,161 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml" lang="en"
xml:lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
+ <title>In-depth Explanation</title>
+ <link href="../css/trailblazer_main.css" rel="stylesheet"
type="text/css" />
+</head>
+
+<body>
+
+<div id="main">
+ <div class="trail">
+ <div class="numbox">5</div>
+ <h2>Conversations</h2>
+ <img src="../img/header_line.gif" />
+
+ <form>
+ <input type="button" value="Close Window"
onclick="window.close()"/>
+ </form>
+
+ <p>
+ The hotel booking "wizard" is implemented by a conversation-scoped
+ stateful session bean. All Seam components are in the
+ conversation scope by default.
+ The <code>HotelBookingAction</code> maintains
+ state associated with the booking process in the Seam conversation
+ scope. This ensures that if the user is working in multiple brower
+ tabs or multiple brower windows, the various conversations are
+ completely isolated from each other.
+ </p>
+ <p>
+ To see this working in practice, right click on the "View Hotel" button
+ in the search screen and select "open in new tab" or "open in new
window",
+ and try working on multiple hotel bookings simultaneously.
+ In the <a href="workspaceExp.html">next step</a>, we will
discuss
+ Seam's built-in components to manage multiple concurrent conversations.
+ </p>
+
+<code class="block">
+@Stateful
+@Name("hotelBooking")
+@LoggedIn
+public class HotelBookingAction implements HotelBooking
+{
+
+ @PersistenceContext(type=EXTENDED)
+ private EntityManager em;
+
+ @In
+ private User user;
+
+ @In(required=false) @Out
+ private Hotel hotel;
+
+ @In(required=false)
+ @Out(required=false)
+ private Booking booking;
+
+ @In(create=true)
+ private FacesMessages facesMessages;
+
+ @In(create=true)
+ private Events events;
+
+ @In
+ private HotelSearching hotelSearch;
+
+ @Logger
+ private Log log;
+
+ private boolean bookingValid;
+
+ @Begin
+ public void selectHotel(Hotel selectedHotel)
+ {
+ hotel = em.merge(selectedHotel);
+ }
+
+ public void bookHotel()
+ {
+ booking = new Booking(hotel, user);
+ Calendar calendar = Calendar.getInstance();
+ booking.setCheckinDate( calendar.getTime() );
+ calendar.add(Calendar.DAY_OF_MONTH, 1);
+ booking.setCheckoutDate( calendar.getTime() );
+ }
+
+
+ public void setBookingDetails()
+ {
+ Calendar calendar = Calendar.getInstance();
+ calendar.add(Calendar.DAY_OF_MONTH, -1);
+ if ( booking.getCheckinDate().before( calendar.getTime() ) )
+ {
+ facesMessages.addToControl("checkinDate", "Check in date must be
a future date");
+ bookingValid=false;
+ }
+ else if ( !booking.getCheckinDate().before( booking.getCheckoutDate() ) )
+ {
+ facesMessages.addToControl("checkoutDate", "Check out date must
be later than check in date");
+ bookingValid=false;
+ }
+ else
+ {
+ bookingValid=true;
+ }
+ }
+
+ public boolean isBookingValid()
+ {
+ return bookingValid;
+ }
+
+ @End
+ public void confirm()
+ {
+ em.persist(booking);
+ facesMessages.add("Thank you, #{user.name}, your confimation number for
#{hotel.name} is #{booking.id}");
+ log.info("New booking: #{booking.id} for #{user.username}");
+ events.raiseTransactionSuccessEvent("bookingConfirmed");
+ }
+
+ @End
+ public void cancel() {}
+
+ @Remove
+ public void destroy() {}
+}</code>
+
+ <p>
+ The conversation begins when the <code>@Begin</code> annotated
+ <code>selectHotel()</code> is called, and ends when
+ the <code>@End</code> annotated
+ <code>confirm()</code> or <code>cancel()</code> is called.
Between the
+ <code>@Begin</code> and <code>@End</code> methods, the
user can do
+ any number of things with the application (i.e., invoke any
+ event handler method or use the BACK button etc.) and the
+ <code>hotelBooking</code> maintains its state throughout the process.
+ When the <code>@End</code> method is called, Seam destroys this
+ component and avoids any memory leak.
+ </p>
+
+ <p>
+ However, none of the <code>HotelBookingAction</code> bean methods
+ may be called outside of a long-running conversation.
+ So if we try to use the
+ back button after the end of the conversation, Seam will redirect to the main page,
with an
+ error message.
+ </p>
+
+
+ <form>
+ <input type="button" value="Close Window"
onclick="window.close()"/>
+ </form>
+
+ </div>
+</div>
+
+</body>
+</html>
Added:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/confirmExp.html
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/confirmExp.html
(rev 0)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/confirmExp.html 2012-08-15
14:28:58 UTC (rev 15048)
@@ -0,0 +1,104 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml" lang="en"
xml:lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
+ <title>In-depth Explanation</title>
+ <link href="../css/trailblazer_main.css" rel="stylesheet"
type="text/css" />
+</head>
+
+<body>
+
+<div id="main">
+ <div class="trail">
+ <div class="numbox">7</div>
+ <h2>Ending Conversations</h2>
+ <img src="../img/header_line.gif" />
+
+ <form>
+ <input type="button" value="Close Window"
onclick="window.close()"/>
+ </form>
+
+ <p>
+ The "Confirm" button is bound to the action method
<code>confirm()</code>
+ of <code>HotelBookingAction</code>.
+ </p>
+
+<code class="block">
+<h:commandButton value="Confirm"
+ action="#{hotelBooking.confirm}"
+ id="confirm"/>
+</code>
+
+ <p>
+ The <code>confirm()</code> method is tagged with the
<code>@End</code> annotation,
+ which ends the long-running conversation and results in all state associated with
+ the conversation being destroyed at the end of the request.
+ Since the <code>pages.xml</code> file specifies a redirect for this
action, the state
+ will not be destroyed
+ until <em>after the redirect completes</em>. Note that even the
success message
+ that we create using the built-in <code>facesMessages</code> component
is transparently
+ propagated across the redirect!
+ </p>
+
+<code class="block">
+ @End
+ public void confirm()
+ {
+ if (booking==null || hotel==null) return "main";
+ em.persist(booking);
+ facesMessages.add("Thank you, #{user.name}, your confimation number " +
+ "for #{hotel.name} is #{booking.id}");
+ log.info("New booking: #{booking.id} for #{user.username}");
+ events.raiseEvent("bookingConfirmed");
+ }
+
+ @End
+ public void cancel() {}
+
+ @Destroy @Remove
+ public void destroy() {}
+}
+</code>
+
+ <p>
+ When the conversation state is finally destroyed, Seam calls the
<code>@Destroy</code> method,
+ which results in removal of the SFSB.
+ </p>
+
+ <p>
+ Notice that the <code>HotelBookingAction.confirm()</code> method
+ raises a <code>bookingConfirmed</code> event before it finishes. The
+ event mechanism allows Seam components to communicate with each other
+ without direct coupling. In this case, the
<code>BookingListAction</code>
+ component captures the <code>bookingConfirmed</code> event and
refreshes
+ the existing booking list for the current user.
+ </p>
+
+<code class="block">
+public class BookingListAction implements BookingList, Serializable
+{
+
+ ... ...
+
+ @Factory
+ @Observer("bookingConfirmed")
+ public void getBookings()
+ {
+ bookings = em.createQuery("from Booking b where b.user.username = " +
+ ":username order by b.checkinDate")
+ .setParameter("username", user.getUsername())
+ .getResultList();
+ }
+}
+</code>
+
+ <form>
+ <input type="button" value="Close Window"
onclick="window.close()"/>
+ </form>
+
+ </div>
+</div>
+
+</body>
+</html>
Added:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/introExp.html
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/introExp.html
(rev 0)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/introExp.html 2012-08-15
14:28:58 UTC (rev 15048)
@@ -0,0 +1,73 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml" lang="en"
xml:lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
+ <title>In-depth Explanation</title>
+ <link href="../css/trailblazer_main.css" rel="stylesheet"
type="text/css" />
+</head>
+
+<body>
+
+<div id="main">
+ <div class="trail">
+ <div class="numbox">1</div>
+ <h2>What is JBoss Seam</h2>
+ <img src="../img/header_line.gif" />
+
+ <p>
+ <center>
+ <form>
+ <INPUT type="button" value="Close Window"
onclick="window.close()">
+ </form>
+ </center>
+ </p>
+
+ <p>
+ EJB 3.0 and JSF are perhaps the most exciting new developments in the Java EE 5
platform.
+ Seam is an innovative new application framework that integrates the EJB 3.0
component model
+ with JSF as a presentation tier. Seam builds upon the standard extension points
provided by
+ both specifications and provides a set of Java annotations that extends the
standard
+ annotations defined by the EJB specification. In addition, Seam introduces several
innovative
+ new ideas: managed conversations, declarative and contextual application state
management,
+ bijection and integrated business process management.
+ </p>
+
+ <p>
+ Traditional web applications are incredibly vulnerable to bugs and performance
problems
+ relating to state management. Developers are forced to handle issues like back
button
+ navigation, multi-window browsing, session size management in an utterly ad-hoc
fashion.
+ Access to transactional components from the web tier has also been problematic.
J2EE
+ provided no way to have simultaneous access to state held in contexts associated
with
+ the web request, and state held in transactional resources accessed via EJB.
Finally,
+ J2EE had no first-class construct for representing state associated with a
long-running
+ business process. Seam tackles all these problems, and provides a uniform model
for
+ stateful components in Java EE 5.
+ </p>
+
+ <p>
+ Like all JBoss software, this entire software stack is free. The full source code
of this
+ sample application is available in the <code>examples/booking</code>
directory of the
+ <a
href="http://www.jboss.com/products/list/downloads#seam">Seam
distribution</a>.
+ <!--
+ There is even a
+ <a target="_blank"
href="http://docs.jboss.com/TrailBlazer/seam-booking/Seam.htm">
+ 10-minute flash demo
+ </a>
+ showing how to build a Seam web application from ground up.
+ -->
+ </p>
+
+ <p>
+ <center>
+ <form>
+ <INPUT type="button" value="Close Window"
onclick="window.close()">
+ </form>
+ </center>
+ </p>
+
+ </div>
+</div>
+
+</body>
+</html>
Added:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/loginExp.html
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/loginExp.html
(rev 0)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/loginExp.html 2012-08-15
14:28:58 UTC (rev 15048)
@@ -0,0 +1,161 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml" lang="en"
xml:lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
+ <title>In-depth Explanation</title>
+ <link href="../css/trailblazer_main.css" rel="stylesheet"
type="text/css" />
+</head>
+
+<body>
+
+<div id="main">
+ <div class="trail">
+ <div class="numbox">2</div>
+ <h2>What happens when you login?</h2>
+ <img src="../img/header_line.gif" />
+
+ <form>
+ <input type="button" value="Close Window"
onclick="window.close()"/>
+ </form>
+
+ <p>
+ The login page is defined using pure XHTML with JSF controls.
+ The form uses JSF EL value binding and method binding
+ expressions to refer to Seam components. For example,
+ <code>#{identity.username}</code> refers to a property of the
+ <code>Identity</code> component and
<code>#{identity.login}</code>
+ refers to a method of the <code>Identity</code> component.
+ </p>
+
+<code class="block">
+<div>
+ <h:outputLabel for="username">Login
Name</h:outputLabel>
+ <h:inputText id="username" value="#{identity.username}"
/>
+</div>
+<div>
+ <h:outputLabel for="password">Password</h:outputLabel>
+ <h:inputSecret id="password" value="#{identity.password}"
/>
+</div>
+
+... ...
+
+<div class="buttonBox">
+ <h:commandButton id="login"
+ action="#{identity.login}"
+ value="Account Login" />
+</div>
+</code>
+
+ <p>
+ After logging in, the <code>User</code> enity bean is mapped to the
Seam
+ context variable named <code>user</code> bean via the
+ <code>@Name</code> annotation. <code>User</code> is
+ a session scoped bean, meaning that the <code>user</code>
+ component value is retained for the entire session for
+ each user. You might also notice there are validation annotation
+ on the data properties. We will discuss those annotations in the
+ <a href="registerExp.html">next step</a>.
+ </p>
+
+<code class="block">
+@Entity
+@Name("user")
+@Scope(SESSION)
+public class User implements Serializable {
+ private String username;
+ private String password;
+ private String name;
+
+ @NotNull
+ @Length(min=5, max=15)
+ public String getPassword() {
+ return password;
+ }
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+
+ @Id
+ @Length(min=4, max=15)
+ @Pattern(regex="^\\w*$", message="not a valid username")
+ public String getUsername () {
+ return username;
+ }
+ public void setUsername (String username) {
+ this.username = username;
+ }
+
+ // ... ...
+}
+</code>
+
+ <p>
+ Seam comes with its own Security framework, based on JAAS. It allows you
+ to perform user authentication by configuring your own authentication method
+ in <code>components.xml</code>.
+ </p>
+
+<code class="block">
+ <security:identity
authenticate-method="#{authenticator.authenticate}"/>
+</code>
+
+ <p>
+ <code>AuthenticatorAction</code> is an EJB 3.0 session bean mapped
+ to the Seam context variable named <code>authenticator</code>. When
+ the login button is clicked, the JSF method binding
+ <code>#{identity.login}</code> is evaluated, and based upon the
previous configuration, the
+ <code>authenticate()</code> method is invoked upon
<code>AuthenticatorAction</code>.
+ </p>
+
+<code class="block">
+@Stateless
+@Scope(EVENT)
+@Name("authenticator")
+public class AuthenticatorAction implements Authenticator
+{
+ @PersistenceContext EntityManager em;
+
+ @Out(required=false, scope = SESSION)
+ private User user;
+
+ public boolean authenticate()
+ {
+ List results = em.createQuery("select u from User u where" +
+ " u.username=#{identity.username}" +
+ " and u.password=#{identity.password}")
+ .getResultList();
+
+ if ( results.size()==0 )
+ {
+ return false;
+ }
+ else
+ {
+ user = (User) results.get(0);
+ return true;
+ }
+ }
+}
+</code>
+
+ <p>
+ The <code>@Out</code>
+ annotation indicates the <code>AuthenticatorAction</code> bean can
change the
+ value of the <code>user</code> context variable and make the new
instance
+ available to other session beans and JSF pages. The query expression
+ makes use of a special syntax in Seam that allows EL expressions to
+ serve as query parameters. This query references the
<code>identity</code> component,
+ a built-in Seam component that provides security functionality.
+ </p>
+
+ <form>
+ <input type="button" value="Close Window"
onclick="window.close()"/>
+ </form>
+
+ </div>
+</div>
+
+</body>
+</html>
Added:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/mainExp.html
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/mainExp.html
(rev 0)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/mainExp.html 2012-08-15
14:28:58 UTC (rev 15048)
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml" lang="en"
xml:lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
+ <title>In-depth Explanation</title>
+ <link href="../css/trailblazer_main.css" rel="stylesheet"
type="text/css" />
+</head>
+
+<body>
+
+<div id="main">
+ <div class="trail">
+ <div class="numbox">4</div>
+ <h2>Stateful components</h2>
+ <img src="../img/header_line.gif" />
+
+ <form>
+ <input type="button" value="Close Window"
onclick="window.close()"/>
+ </form>
+
+ <p>
+ The hotel search page is backed by the a stateful session bean named
+ <code>hotelSearch</code> and implemented by the class
+ <code>HotelSearchingAction</code>.
+ </p>
+
+<code class="block">
+<h:inputText id="searchString"
value="#{hotelSearch.searchString}" >
+ <a:support event="onkeyup"
actionListener="#{hotelSearch.find}"
+ reRender="searchResults"/>
+</h:inputText>
+
+<h:selectOneMenu value="#{hotelSearch.pageSize}"
id="pageSize">
+ <f:selectItem itemLabel="5" itemValue="5"/>
+ <f:selectItem itemLabel="10" itemValue="10"/>
+ <f::selectItem itemLabel="20" itemValue="20"/>
+</h:selectOneMenu>
+</code>
+
+ <p>
+ When the button is clicked, the form is submitted and JSF sets the value
+ of the text box and drop down menu onto the <code>searchString</code>
and
+ <code>pageSize</code> attributes of
<code>HotelSearchingAction</code>
+ before calling the <code>find()</code> action listener method.
We've used a
+ session-scope stateful bean because we want it's state (the search results) to
+ be held in the session between requests to the server. The
<code><a:support></code>
+ tax specfies that after a keypress, the contents of the
<code><a:outputPanel></code> whose
+ id is <code>searchResults</code> should be rerendererd. This is done
through an AJAX-style
+ call back to the server with no additional code required of the application.
+ </p>
+
+<code class="block">
+@Stateful
+@Name("hotelSearch")
+(a)Scope(ScopeType.SESSION)
+@LoggedIn
+public class HotelSearchingAction implements HotelSearching
+{
+ @PersistenceContext
+ private EntityManager em;
+
+ private String searchString;
+ private int pageSize = 10;
+ private int page;
+
+ @DataModel
+ private List<Hotel> hotels;
+
+ public void find()
+ {
+ page = 0;
+ queryHotels();
+ }
+ public void nextPage()
+ {
+ page++;
+ queryHotels();
+ }
+
+ private void queryHotels()
+ {
+ hotels = 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(pageSize)
+ .setFirstResult( page * pageSize )
+ .getResultList();
+ }
+
+ public boolean isNextPageAvailable()
+ {
+ return hotels!=null && hotels.size()==pageSize;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public void setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ @Factory(value="pattern", scope=ScopeType.EVENT)
+ public String getSearchPattern()
+ {
+ return searchString==null ?
+ "%" : '%' + searchString.toLowerCase().replace('*',
'%') + '%';
+ }
+
+ public String getSearchString()
+ {
+ return searchString;
+ }
+
+ public void setSearchString(String searchString)
+ {
+ this.searchString = searchString;
+ }
+
+ @Remove
+ public void destroy() {}
+}</code>
+
+ <p>
+ The <code>find()</code> method retrieves a list of hotels from the
database and
+ initializes the <code>hotels</code> field. The
<code>hotels</code> field is marked
+ with the <code>@DataModel</code> annotation, so when the
<code>find()</code> method
+ returns, Seam outjects an instance of <code>ListDataModel</code> to a
context
+ variable named <code>hotels</code>. So, when the search page is
re-rendered, the
+ result list is available to the JSF <code>dataTable</code>.
+ Each row of the data table has an associated command button or link
+ (see below).
+ </p>
+
+<code class="block">
+<h:outputText value="No Hotels Found"
+ rendered="#{hotels != null and hotels.rowCount==0}"/>
+<h:dataTable value="#{hotels}" var="hot"
rendered="#{hotels.rowCount>0}">
+ <h:column>
+ <f:facet name="header">Name</f:facet>
+ #{hot.name}
+ </h:column>
+ <h:column>
+ <f:facet name="header">Address</f:facet>
+ #{hot.address}
+ </h:column>
+ <h:column>
+ <f:facet name="header">City, State</f:facet>
+ #{hot.city}, #{hot.state}
+ </h:column>
+ <h:column>
+ <f:facet name="header">Zip</f:facet>
+ #{hot.zip}
+ </h:column>
+ <h:column>
+ <f:facet name="header">Action</f:facet>
+ <s:link value="View Hotel"
+ action="#{hotelBooking.selectHotel(hot)}"/>
+ </h:column>
+</h:dataTable>
+</code>
+
+ <p>
+ The "View Hotel" link is the above mentioned command link associated
+ with each row of the data table. It is implemented
+ using a Seam <code><s:link></code>, which is part of
Seam's
+ extension of JSF controls.
+ This JSF control let's us call an action, and pass a request parameter,
without
+ submitting any JSF form. The advantage of
<code><s:link></code> is that,
+ unlike a standard JSF <code><h:commandLink></code>,
there is no JavaScript
+ used, so "open link in new tab" works seamlessly.
+ </p>
+ <p>
+ When this link is clicked, the <code>selectHotel()</code> method of
the
+ <code>HotelBookingAction</code> bean is called with the
<code>hot</code>
+ parameter that is specified in the query. The parameter values are evaluated
+ at invocation time, not when the link is generated, so the
<code><s:link></code>
+ tag adds a dataModelSelection parameter that indicates the value of the
+ <code>hot</code> loop variable for the given row.</p>
+ <p> The <code>selectHotel()</code> method merges the selected
hotel into
+ the current persistence context (in case the same
+ hotel has been accessed before in the same session),
+ and starts a Seam conversation. We will discuss Seam conversations
+ in the next step.
+ </p>
+
+<code class="block">
+@Stateful
+@Name("hotelBooking")
+@LoggedIn
+public class HotelBookingAction implements HotelBooking
+{
+
+ ... ...
+
+ @Begin
+ public void selectHotel(Hotel selectedHotel)
+ {
+ hotel = em.merge(selectedHotel);
+ }
+}
+</code>
+
+ <form>
+ <input type="button" value="Close Window"
onclick="window.close()"/>
+ </form>
+
+ </div>
+</div>
+
+</body>
+</html>
Added:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/registerExp.html
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/registerExp.html
(rev 0)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/registerExp.html 2012-08-15
14:28:58 UTC (rev 15048)
@@ -0,0 +1,229 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml" lang="en"
xml:lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
+ <title>In-depth Explanation</title>
+ <link href="../css/trailblazer_main.css" rel="stylesheet"
type="text/css" />
+</head>
+
+<body>
+
+<div id="main">
+ <div class="trail">
+ <div class="numbox">3</div>
+ <h2>What happens in the registration process?</h2>
+ <img src="img/header_line.gif" />
+
+ <form>
+ <input type="button" value="Close Window"
onclick="window.close()"/>
+ </form>
+
+ <p>
+ The register.xhtml JSF form captures the user input for new account
+ registration. It validates the user input, binds the data to a
+ Seam data component, and invokes a Seam UI event handler method
+ when the form is submitted.
+ </p>
+
+<code class="block">
+<s:validateAll>
+<div class="entry">
+ <div class="label">
+ <h:outputLabel
for="username">Username:</h:outputLabel>
+ </div>
+ <div class="input">
+ <h:inputText id="username"
value="#{user.username}"/><br/>
+ <span class="errors"><h:message
for="username" /></span>
+ </div>
+</div>
+<div class="entry">
+ <div class="label">
+ <h:outputLabel for="name">Real
Name:</h:outputLabel>
+ </div>
+ <div class="input">
+ <h:inputText id="name" value="#{user.name}"
/><br/>
+ <span class="errors"><h:message for="name"
/></span>
+ </div>
+</div>
+</s:validateAll>
+
+... ...
+
+ <div class="input">
+ <h:commandButton value="Register"
+ action="#{register.register}"
+ class="button"/>
+ <h:commandButton value="Cancel" action="login"
class="button"/>
+ </div>
+</code>
+
+ <p>
+ The form fields are bound to properties of a Seam component named
+ <code>user</code> via JSF EL value binding expressions such as
+ <code>#{user.username}</code>. The form submit button is bound
+ to the <code>register()</code> method of the Seam component named
+ <code>register</code> using the JSF method binding expression
+ <code>#{register.register}</code>.
+ </p>
+
+ <p>
+ Notice that the input fields are enclosed by a
<code><s:validateAll</code>
+ tag. This tag is part of Seam's extension to JSF. It tells the Seam
+ runtime to validate those input fields when the form is submitted.
+ The validation conditions are specified on the entity bean classes
+ those input fields map to (e.g., here the validation condition is
+ on the <code>User</code> class, see later).
+ This JSF form also includes <code><h:message></code>
tags that
+ will display the results of any JSF validation failures.
+ </p>
+
+ <p>
+ The <code>User</code> class is an EJB 3.0 entity bean with a
+ <code>@Name</code> annotation that binds the bean instance to a
+ context variable named <code>user</code>. In addition to the standard
+ EJB 3.0 O/R mapping metadata, this bean features several Hibernate
+ Validator annotations such as
+ <code>@NotNull</code>, <code>@Length</code>. Due to the
+ <code><s:validateAll</code> tag in the form, these constraints
are
+ automatically validated by Seam when the form is submitted. If the user
+ enters invalid data in the JSF form, the form will be redisplayed with
+ error messages.
+ </p>
+
+<code class="block">
+@Entity
+@Name("user")
+@Scope(SESSION)
+public class User implements Serializable
+{
+ private String username;
+ private String password;
+ private String name;
+
+ public User(String name, String password, String username)
+ {
+ this.name = name;
+ this.password = password;
+ this.username = username;
+ }
+
+ public User() {}
+
+ @NotNull
+ @Length(max=100)
+ public String getName()
+ {
+ return name;
+ }
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ @NotNull
+ @Length(min=5, max=15)
+ public String getPassword()
+ {
+ return password;
+ }
+ public void setPassword(String password)
+ {
+ this.password = password;
+ }
+
+ @Id
+ @Length(min=5, max=15)
+ public String getUsername()
+ {
+ return username;
+ }
+ public void setUsername(String username)
+ {
+ this.username = username;
+ }
+
+}</code>
+
+ <p>
+ <code>RegisterAction</code> is an EJB 3.0 stateful session bean
+ bound to the Seam context variable named <code>register</code>.
+ The <code>register()</code> method is invoked when the form is
+ submitted.
+ </p>
+
+<code class="block">
+@Stateful
+@Scope(EVENT)
+@Name("register")
+public class RegisterAction implements Register
+{
+
+ @In
+ private User user;
+
+ @PersistenceContext
+ private EntityManager em;
+
+ @In(create=true)
+ private transient FacesMessages facesMessages;
+
+ private String verify;
+
+ public String register()
+ {
+ if ( user.getPassword().equals(verify) )
+ {
+ List existing = em.createQuery("select username from User " +
+ "where username=:username")
+ .setParameter("username", user.getUsername())
+ .getResultList();
+ if (existing.size()==0)
+ {
+ em.persist(user);
+ return "login";
+ }
+ else
+ {
+ facesMessages.add("username #{user.username} already exists");
+ return null;
+ }
+ }
+ else
+ {
+ facesMessages.add("re-enter your password");
+ verify=null;
+ return null;
+ }
+ }
+
+ public String getVerify()
+ {
+ return verify;
+ }
+
+ public void setVerify(String verify)
+ {
+ this.verify = verify;
+ }
+
+ @Destroy @Remove
+ public void destroy() {}
+}</code>
+
+ <p>
+ The <code>@In</code> annotations inject Seam components into the
<code>RegisterAction</code>
+ bean. The <code>user</code> component is our entity bean, of course.
The <code>facesMessages</code>
+ component is a built-in Seam component that makes it very easy to display
templated and localized
+ messages to the user, even when redirect after post is used.
+ </p>
+
+ <form>
+ <input type="button" value="Close Window"
onclick="window.close()"/>
+ </form>
+
+ </div>
+</div>
+
+</body>
+</html>
Added:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/workspaceExp.html
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/workspaceExp.html
(rev 0)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/exp/workspaceExp.html 2012-08-15
14:28:58 UTC (rev 15048)
@@ -0,0 +1,92 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml" lang="en"
xml:lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
+ <title>In-depth Explanation</title>
+ <link href="../css/trailblazer_main.css" rel="stylesheet"
type="text/css" />
+</head>
+
+<body>
+
+<div id="main">
+ <div class="trail">
+ <div class="numbox">6</div>
+ <h2>The Workspace List</h2>
+ <img src="../img/header_line.gif" />
+
+ <p>
+ <center>
+ <form>
+ <INPUT type="button" value="Close Window"
onclick="window.close()">
+ </form>
+ </center>
+ </p>
+
+ <p>
+ The workspace list allows the user to switch between multiple
+ conversations from the same browser tab. There is no Java code
+ to write, just the following JSF code to include:
+ </p>
+
+<code class="block">
+<h:dataTable value="#{conversationList}" var="entry">
+ <h:column>
+ <h:commandLink action="#{entry.select}"
value="#{entry.description}"/>
+
+ <h:outputText value="[current]"
rendered="#{entry.current}"/>
+ </h:column>
+ <h:column>
+ <h:outputText value="#{entry.startDatetime}">
+ <f:convertDateTime type="time" pattern="hh:mm"/>
+ </h:outputText>
+ -
+ <h:outputText value="#{entry.lastDatetime}">
+ <f:convertDateTime type="time" pattern="hh:mm"/>
+ </h:outputText>
+ </h:column>
+</h:dataTable>
+</code>
+
+ <p>
+ We do need to specify what text will be displayed by
<code>#{entry.description}</code>.
+ We do this by setting the <code>description</code> value for each page
in <code>pages.xml</code>.
+ </p>
+
+<code class="block">
+<pages>
+ <!-- ... -->
+ <page view-id="/hotel.xhtml"
+ conversation-required="true"
+ login-required="true">
+
+ <description>View hotel: #{hotel.name}</description>
+ <!-- ... -->
+ </page>
+
+ <page view-id="/book.xhtml"
+ conversation-required="true"
+ login-required="true">
+
+ <description>Book hotel: #{hotel.name}</description>
+ <!-- ... -->
+ </page>
+<pages>
+</code>
+
+ <p>
+ Note that you don't need the <code>pages.xml</code> file if you
don't want the
+ workspace list in your application.
+ </p>
+
+ <p>
+ <form>
+ <input type="button" value="Close Window"
onclick="window.close()"/>
+ </form>
+ </p>
+
+ </div>
+</div>
+
+</body>
+</html>
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/home.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/home.xhtml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/home.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<h:html
xmlns="http://www.w3.org/1999/xhtml"
+<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:f="http://java.sun.com/jsf/core"
@@ -9,7 +9,7 @@
<title>JBoss Suites: Seam Framework</title>
<link href="css/screen.css" rel="stylesheet"
type="text/css" />
</h:head>
-<h:body id="pgHome">
+<body id="pgHome">
<f:view>
<div id="document">
<div id="header">
@@ -20,16 +20,16 @@
<h:form id="login">
<fieldset>
<div>
- <h:outputLabel for="username">Login Name</h:outputLabel>
+ <h:outputLabel id="UsernameLabel" for="username">Login
Name</h:outputLabel>
<h:inputText id="username" value="#{identity.username}"
style="width: 175px;"/>
- <div class="errors"><h:message
for="username"/></div>
+ <div class="errors"><h:message id="UsernameMessage"
for="username"/></div>
</div>
<div>
- <h:outputLabel for="password">Password</h:outputLabel>
+ <h:outputLabel id="PasswordLabel"
for="password">Password</h:outputLabel>
<h:inputSecret id="password" value="#{identity.password}"
style="width: 175px;"/>
</div>
- <div class="errors"><h:messages
globalOnly="true"/></div>
- <div class="buttonBox"><h:commandButton id="login"
action="#{identity.login}" value="Account Login"/></div>
+ <div class="errors"><h:messages id="messages"
globalOnly="true"/></div>
+ <div class="buttonBox"><h:commandButton id="login"
action="#{identity.quietLogin}" value="Account
Login"/></div>
<div class="notes"><s:link id="register"
view="/register.xhtml" value="Register New User"/></div>
<div class="subnotes">
Or use a demo account:
@@ -41,9 +41,41 @@
</fieldset>
</h:form>
</div>
+ <div id="content">
+ <div class="section">
+
+ <h1>About this example application</h1>
+
+ <p>
+ This sample application demonstrates how easy it is to develop stateful web
+ applications using JBoss Seam. Just register, login, and book a room to see
+ Seam in action. Throughout the application you'll see popup links like
+ the ones at the bottom of this page. Click them to see how the application
+ works under the hood.
+ </p>
+
+ <p>
+ Note: Please do NOT enter personal information or your credit card number in
+ this sample application.
+ </p>
+
+ <p>
+ <a href="#"
onclick="window.open('exp/introExp.html','exp','width=752,height=500,scrollbars=yes');">
+ What is JBoss Seam?
+ </a>
+ </p>
+
+ <p>
+ <a href="#"
onclick="window.open('exp/loginExp.html','exp','width=752,height=500,scrollbars=yes');">
+ What happens when I login?
+ </a>
+ </p>
+
+ </div>
+ </div>
</div>
<div id="footer">Created with JBoss EJB 3.0, Seam, JSF (Mojarra), and
Facelets</div>
</div>
</f:view>
-</h:body>
-</h:html>
+</body>
+</html>
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/hotel.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/hotel.xhtml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/hotel.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -3,61 +3,54 @@
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
-
xmlns:s="http://jboss.org/schema/seam/taglib"
+
xmlns:s="http://jboss.org/schema/seam/taglib"
template="template.xhtml">
<!-- content -->
<ui:define name="content">
+
<div class="section">
<h1>View Hotel</h1>
</div>
+
<div class="section">
- <div class="entry">
- <div class="label">Name:</div>
- <div class="output">#{hotel.name}</div>
+ <ui:include src="hotelview.xhtml"/>
+
+ <div class="buttonBox">
+ <h:form id="hotel">
+ <h:commandButton id="bookHotel"
action="#{hotelBooking.bookHotel}" value="Book Hotel"/>
+  
+ <h:commandButton id="cancel" action="#{hotelBooking.cancel}"
value="Back to Search"/>
+ </h:form>
</div>
- <div class="entry">
- <div class="label">Address:</div>
- <div class="output">#{hotel.address}</div>
- </div>
- <div class="entry">
- <div class="label">City:</div>
- <div class="output">#{hotel.city}</div>
- </div>
- <div class="entry">
- <div class="label">State:</div>
- <div class="output">#{hotel.state}</div>
- </div>
- <div class="entry">
- <div class="label">Zip:</div>
- <div class="output">#{hotel.zip}</div>
- </div>
- <div class="entry">
- <div class="label">Country:</div>
- <div class="output">#{hotel.country}</div>
- </div>
- <div class="entry">
- <div class="label">Nightly rate:</div>
- <div class="output">
- <h:outputText value="#{hotel.price}">
- <f:convertNumber type="currency"
- currencySymbol="$"/>
- </h:outputText>
- </div>
- </div>
+
+
</div>
-<div class="section">
- <h:form id="hotel">
- <fieldset class="buttonBox">
- <h:commandButton id="bookHotel"
action="#{hotelBooking.bookHotel}" value="Book Hotel"/> 
- <h:commandButton id="cancel" action="#{hotelBooking.cancel}"
value="Back to Search"/>
- </fieldset>
- </h:form>
-</div>
+
</ui:define>
<!-- sidebar -->
<ui:define name="sidebar">
+
+<h1>Don't kill your database</h1>
+<p>
+ Keeping conversational state in memory in the middle tier is a great way to
+ improve your application's scalability. It saves hitting the database every
+ time we refresh a page, to re-read the data we were just looking at five
+ seconds ago. By using Seam's conversation context, we get a natural cache
+ of data associated with the what the user is currently doing. By nature,
+ this cache has a more efficient eviction policy than the MRU-type algorithms
+ used by a typical second-level data cache in an O/R mapping engine like
+ Hibernate (at least for some kinds of data). Of course, you should use
+ a clever combination of second-level caching and conversational data
+ caching to achieve the best performance for your application.
+</p>
+<p>
+ <a href="#"
onclick="window.open('exp/bookingExp.html','exp','width=752,height=500,scrollbars=yes');">
+ How does the hotel booking wizard work?
+ </a>
+</p>
+
</ui:define>
</ui:composition>
Added:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/hotelview.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/hotelview.xhtml
(rev 0)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/hotelview.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -0,0 +1,45 @@
+<!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:h="http://java.sun.com/jsf/html"
+
xmlns:f="http://java.sun.com/jsf/core"
+
xmlns:s="http://jboss.org/schema/seam/taglib">
+
+ <s:decorate id="DecorateName" template="display.xhtml">
+ <ui:define name="label">Name:</ui:define>
+ #{hotel.name}
+ </s:decorate>
+
+ <s:decorate id="DecorateAddress" template="display.xhtml">
+ <ui:define name="label">Address:</ui:define>
+ #{hotel.address}
+ </s:decorate>
+
+ <s:decorate id="DecorateCity" template="display.xhtml">
+ <ui:define name="label">City:</ui:define>
+ #{hotel.city}
+ </s:decorate>
+
+ <s:decorate id="DecorateState" template="display.xhtml">
+ <ui:define name="label">State:</ui:define>
+ #{hotel.state}
+ </s:decorate>
+
+ <s:decorate id="DecorateZip" template="display.xhtml">
+ <ui:define name="label">Zip:</ui:define>
+ #{hotel.zip}
+ </s:decorate>
+
+ <s:decorate id="DecorateCountry" template="display.xhtml">
+ <ui:define name="label">Country:</ui:define>
+ #{hotel.country}
+ </s:decorate>
+
+ <s:decorate id="DecorateNightlyRate"
template="display.xhtml">
+ <ui:define name="label">Nightly rate:</ui:define>
+ <h:outputText id="HotelPrice" value="#{hotel.price}">
+ <f:convertNumber type="currency" currencySymbol="$"/>
+ </h:outputText>
+ </s:decorate>
+
+</ui:composition>
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/main.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/main.xhtml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/main.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -11,59 +11,60 @@
<ui:define name="content">
<div class="section">
- <h:form id="main">
<span class="errors">
<h:messages id="messages" globalOnly="true"/>
</span>
- <h1>Search Hotels</h1>
- <fieldset>
- <h:inputText id="searchString"
value="#{hotelSearch.searchString}" style="width: 165px;">
- <a:ajax event="keyup" listener="#{hotelSearch.find}"
render="searchResults" />
- </h:inputText>
+ <h1>Search Hotels</h1>
+
+ <h:form id="searchCriteria">
+ <fieldset>
+ <h:inputText id="searchString"
value="#{hotelSearch.searchString}" style="width: 165px;">
+ <a:ajax event="keyup" render="searchResults"
listener="#{hotelSearch.find}"/>
+ </h:inputText>
 
- <a:commandButton id="findHotels" value="Find Hotels"
action="#{hotelSearch.find}" reRender="searchResults"/>
+ <a:commandButton id="findHotels" value="Find Hotels"
actionListener="#{hotelSearch.find}" render="searchResults"/>
 
- <a:status>
- <f:facet name="start">
- <h:graphicImage id="Spinner"
value="/img/spinner.gif"/>
+ <a:status id="status">
+ <f:facet id="StartStatus" name="start">
+ <h:graphicImage id="SpinnerGif"
value="/img/spinner.gif"/>
</f:facet>
</a:status>
<br/>
- <h:outputLabel for="pageSize">Maximum
results:</h:outputLabel> 
- <h:selectOneMenu value="#{hotelSearch.pageSize}"
id="pageSize">
- <f:selectItem itemLabel="5" itemValue="5"/>
- <f:selectItem itemLabel="10" itemValue="10"/>
- <f:selectItem itemLabel="20" itemValue="20"/>
+ <h:outputLabel id="MaximumResultsLabel"
for="pageSize">Maximum results:</h:outputLabel> 
+ <h:selectOneMenu id="pageSize"
value="#{hotelSearch.pageSize}">
+ <f:selectItem id="PageSize5" itemLabel="5"
itemValue="5"/>
+ <f:selectItem id="PageSize10" itemLabel="10"
itemValue="10"/>
+ <f:selectItem id="PageSize20" itemLabel="20"
itemValue="20"/>
</h:selectOneMenu>
</fieldset>
+ </h:form>
- </h:form>
</div>
<a:outputPanel id="searchResults">
<div class="section">
<h:outputText id="NoHotelsFoundMessage" value="No Hotels Found"
rendered="#{hotels != null and hotels.rowCount==0}"/>
<h:dataTable id="hotels" value="#{hotels}" var="hot"
rendered="#{hotels.rowCount>0}">
- <h:column>
- <f:facet name="header">Name</f:facet>
+ <h:column id="column1">
+ <f:facet id="NameFacet" name="header">Name</f:facet>
#{hot.name}
</h:column>
- <h:column>
- <f:facet name="header">Address</f:facet>
+ <h:column id="column2">
+ <f:facet id="AddressFacet"
name="header">Address</f:facet>
#{hot.address}
</h:column>
- <h:column>
- <f:facet name="header">City, State</f:facet>
+ <h:column id="column3">
+ <f:facet id="CityStateFacet" name="header">City,
State</f:facet>
#{hot.city}, #{hot.state}, #{hot.country}
</h:column>
- <h:column>
- <f:facet name="header">Zip</f:facet>
+ <h:column id="column4">
+ <f:facet id="ZipFacet" name="header">Zip</f:facet>
#{hot.zip}
</h:column>
- <h:column>
- <f:facet name="header">Action</f:facet>
+ <h:column id="column5">
+ <f:facet id="ActionFacet"
name="header">Action</f:facet>
<s:link id="viewHotel" value="View Hotel"
action="#{hotelBooking.selectHotel(hot)}"/>
</h:column>
</h:dataTable>
@@ -76,34 +77,34 @@
</div>
<div class="section">
<h:form id="bookings">
- <h:outputText value="No Bookings Found"
rendered="#{bookings.rowCount==0}"/>
+ <h:outputText id="NoBookingsFoundMessage" value="No Bookings
Found" rendered="#{bookings.rowCount==0}"/>
<h:dataTable id="bookings" value="#{bookings}"
var="book" rendered="#{bookings.rowCount>0}">
- <h:column>
- <f:facet name="header">Name</f:facet>
+ <h:column id="column1">
+ <f:facet id="NameFacet" name="header">Name</f:facet>
#{book.hotel.name}
</h:column>
- <h:column>
- <f:facet name="header">Address</f:facet>
+ <h:column id="column2">
+ <f:facet id="AddressFacet"
name="header">Address</f:facet>
#{book.hotel.address}
</h:column>
- <h:column>
- <f:facet name="header">City, State</f:facet>
+ <h:column id="column3">
+ <f:facet id="CityStateFacet" name="header">City,
State</f:facet>
#{book.hotel.city}, #{book.hotel.state}
</h:column>
- <h:column>
- <f:facet name="header">Check in date</f:facet>
- <h:outputText value="#{book.checkinDate}"/>
+ <h:column id="column4">
+ <f:facet id="CheckInDateFacet" name="header">Check
in date</f:facet>
+ <h:outputText id="BookingCheckInDate"
value="#{book.checkinDate}"/>
</h:column>
- <h:column>
- <f:facet name="header">Check out date</f:facet>
- <h:outputText value="#{book.checkoutDate}"/>
+ <h:column id="column5">
+ <f:facet id="CheckOutDateFacet" name="header">Check
out date</f:facet>
+ <h:outputText id="BookingCheckOutDate"
value="#{book.checkoutDate}"/>
</h:column>
- <h:column>
- <f:facet name="header">Confirmation number</f:facet>
+ <h:column id="column6">
+ <f:facet id="ConfNumberFacet" name="header">Confirmation
number</f:facet>
#{book.id}
</h:column>
- <h:column>
- <f:facet name="header">Action</f:facet>
+ <h:column id="column7">
+ <f:facet id="ActionFacet"
name="header">Action</f:facet>
<h:commandLink id="cancel" value="Cancel"
action="#{bookingList.cancel}"/>
</h:column>
</h:dataTable>
@@ -114,6 +115,25 @@
<!-- sidebar -->
<ui:define name="sidebar">
+
+<h1>State management in Seam</h1>
+<p>
+ State in Seam is <em>contextual</em>. When you click "Find
Hotels", the application
+ retrieves a list of hotels from the database and caches it in the session context.
When you
+ navigate to one of the hotel records by clicking the "View Hotel" link, a
<em>conversation</em>
+ begins. The conversation is attached to a particular tab, in a particular browser
window. You can
+ navigate to multiple hotels using "open in new tab" or "open in new
window" in your web browser.
+ Each window will execute in the context of a different conversation. The application
keeps state
+ associated with your hotel booking in the conversation context, which ensures that the
concurrent
+ conversations do not interfere with each other.
+</p>
+
+<p>
+ <a href="#"
onclick="window.open('exp/mainExp.html','exp','width=752,height=500,scrollbars=yes');">
+ How does the search page work?
+ </a>
+</p>
+
</ui:define>
</ui:composition>
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/password.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/password.xhtml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/password.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -8,60 +8,42 @@
<!-- content -->
<ui:define name="content">
+
<div class="section">
<h1>Change Your Password</h1>
</div>
+
<div class="section">
+
+ <div class="entry errors">
+ <h:messages id="messages" globalOnly="true"/>
+ </div>
+
<h:form id="setpassword">
- <f:facet name="aroundInvalidField">
- <s:span id="Error" styleClass="errors"/>
- </f:facet>
- <f:facet name="afterInvalidField">
- <s:div id="Message" styleClass="errors">
- <s:message/>
- </s:div>
- </f:facet>
-
<fieldset>
- <div class="entry">
- <div class="label"><h:outputLabel
for="password">Password:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="PasswordDecorate">
- <h:inputSecret id="password" value="#{user.password}"
required="true">
- <!--<s:validate/>-->
- <f:validator
validatorId="org.jboss.seam.ui.ModelValidator"/>
- </h:inputSecret>
- </s:decorate>
- </div>
- </div>
+ <s:decorate id="PasswordDecorate" template="edit.xhtml">
+ <ui:define name="label">Password:</ui:define>
+ <h:inputSecret id="password" value="#{user.password}"
required="true"/>
+ </s:decorate>
- <div class="entry">
- <div class="label"><h:outputLabel
for="verify">Verify:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="VerifyDecorate">
- <h:inputSecret id="verify" value="#{changePassword.verify}"
required="true"/>
- </s:decorate>
- </div>
- </div>
+ <s:decorate id="VerifyDecorate" template="edit.xhtml">
+ <ui:define name="label">Verify:</ui:define>
+ <h:inputSecret id="verify" value="#{changePassword.verify}"
required="true"/>
+ </s:decorate>
- <div class="entry errors">
- <h:messages id="Messages" globalOnly="true"/>
+ <div class="buttonBox">
+ <h:commandButton id="change" value="Change"
action="#{changePassword.changePassword}"/>
+  
+ <s:button id="cancel" value="Cancel"
view="/main.xhtml"/>
</div>
- <div class="entry">
- <div class="label"> </div>
- <div class="input">
- <h:commandButton id="change" value="Change"
action="#{changePassword.changePassword}"/> 
- <s:button id="cancel" value="Cancel"
view="/main.xhtml"/>
- </div>
- </div>
-
</fieldset>
</h:form>
</div>
+
</ui:define>
<!-- sidebar -->
@@ -79,4 +61,4 @@
</p>
</ui:define>
-</ui:composition>
+</ui:composition>
\ No newline at end of file
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/register.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/register.xhtml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/register.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<h:html
xmlns="http://www.w3.org/1999/xhtml"
+<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:f="http://java.sun.com/jsf/core"
@@ -10,93 +10,93 @@
<title>JBoss Suites: Seam Framework</title>
<link href="css/screen.css" rel="stylesheet"
type="text/css" />
</h:head>
-<h:body id="pgHome">
+
+<body id="pgHome">
+
<div id="document">
+
<div id="header">
<div id="title"><img src="img/hdr.title.gif"
alt="JBoss Suites: seam framework demo"/></div>
</div>
+
<div id="container">
+
+ <div id="sidebar">
+ <h1>Integrated multi-layer validation</h1>
+ <p>
+ Robust applications need data validation in several different places. Seam
integrates Hibernate Validator,
+ a set of annotations for expressing data model constraints in your domain model
classes. Then, these
+ constraints are applied almost completely transparently at three levels of the
application: by Seam when
+ the user first enters data, by EJB before persisting data to the database, and, if
you use Hibernate to
+ generate your database schema, by the database constraints themselves. Multi-layer
validation hardens
+ your application and protects your data. Even better, it's self-documenting,
and easy to change when
+ your business rules change.
+ </p>
+ <p>
+ <a href="#"
onclick="window.open('exp/registerExp.html','exp','width=752,height=500,scrollbars=yes');">
+ What happens when I register?
+ </a>
+ </p>
+ </div>
+
<div id="content">
+
<div class="section">
<h1>Register</h1>
</div>
+
<div class="section">
- <h:form id="register">
+ <div class="entry errors">
+ <h:messages id="messages" globalOnly="true"/>
+ </div>
+
+ <h:form id="registration">
<fieldset>
- <s:validateAll>
-
- <f:facet name="aroundInvalidField">
- <s:span styleClass="errors"/>
- </f:facet>
- <f:facet name="afterInvalidField">
- <s:div styleClass="errors">
- <s:message/>
- </s:div>
- </f:facet>
-
- <div class="entry">
- <div class="label"><h:outputLabel
for="username">Username:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="usernameDecorate">
- <h:inputText id="username" value="#{user.username}"
required="true">
- <a:ajax event="blur"
render="usernameDecorate"/>
- </h:inputText>
- </s:decorate>
- </div>
- </div>
-
- <div class="entry">
- <div class="label"><h:outputLabel for="name">Real
Name:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="nameDecorate">
- <h:inputText id="name" value="#{user.name}"
required="true">
- <a:ajax event="blur"
render="nameDecorate"/>
- </h:inputText>
- </s:decorate>
- </div>
- </div>
-
- <div class="entry">
- <div class="label"><h:outputLabel
for="password">Password:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="passwordDecorate">
- <h:inputSecret id="password" value="#{user.password}"
required="true"/>
- </s:decorate>
- </div>
- </div>
-
- <div class="entry">
- <div class="label"><h:outputLabel
for="verify">Verify Password:</h:outputLabel></div>
- <div class="input">
- <s:decorate id="verifyDecorate">
- <h:inputSecret id="verify" value="#{register.verify}"
required="true"/>
- </s:decorate>
- </div>
- </div>
-
- </s:validateAll>
+ <s:decorate id="usernameDecorate" template="edit.xhtml">
+ <ui:define name="label">Username:</ui:define>
+ <h:inputText id="username" value="#{user.username}"
required="true">
+ <a:ajax event="blur" render="usernameDecorate"/>
+ </h:inputText>
+ </s:decorate>
- <div class="entry errors">
- <h:messages id="messages" globalOnly="true"/>
- </div>
+ <s:decorate id="nameDecorate" template="edit.xhtml">
+ <ui:define name="label">Real Name:</ui:define>
+ <h:inputText id="name" value="#{user.name}"
required="true">
+ <a:ajax event="blur" render="nameDecorate"/>
+ </h:inputText>
+ </s:decorate>
- <div class="entry">
- <div class="label"> </div>
- <div class="input">
- <h:commandButton id="register" value="Register"
action="#{register.register}"/> 
- <s:button id="cancel" value="Cancel"
view="/home.xhtml"/>
- </div>
+ <s:decorate id="passwordDecorate" template="edit.xhtml">
+ <ui:define name="label">Password:</ui:define>
+ <h:inputSecret id="password" value="#{user.password}"
required="true"/>
+ </s:decorate>
+
+ <s:decorate id="verifyDecorate" template="edit.xhtml">
+ <ui:define name="label">Verify Password:</ui:define>
+ <h:inputSecret id="verify" value="#{register.verify}"
required="true"/>
+ </s:decorate>
+
+ <div class="buttonBox">
+ <h:commandButton id="register" value="Register"
action="#{register.register}"/>
+  
+ <s:button id="cancel" value="Cancel"
view="/home.xhtml"/>
</div>
-
+
</fieldset>
</h:form>
- </div>
+ </div>
+
</div>
+
</div>
- <div id="footer">Created with JBoss EJB 3.0, Seam, JSF (Mojarra), and
Facelets</div>
+
+ <div id="footer">Created with JBoss EJB 3.0, Seam, JSF (Mojarra) and
Facelets</div>
+
</div>
-</h:body>
-</h:html>
+
+</body>
+
+</html>
Modified:
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/template.xhtml
===================================================================
---
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/template.xhtml 2012-08-15
12:53:43 UTC (rev 15047)
+++
branches/community/Seam_2_3/examples-ee6/groovybooking/groovybooking-web/src/main/webapp/template.xhtml 2012-08-15
14:28:58 UTC (rev 15048)
@@ -1,14 +1,19 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<h: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:s="http://jboss.org/schema/seam/taglib">
+<f:view contentType="text/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:f="http://java.sun.com/jsf/core"
+
xmlns:s="http://jboss.org/schema/seam/taglib">
+
+<html>
<h:head>
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8" />
<title>JBoss Suites: Seam Framework</title>
<link href="css/screen.css" rel="stylesheet"
type="text/css" />
+ <ui:insert name="head"/>
</h:head>
-<h:body>
+<body>
<div id="document">
<div id="header">
@@ -29,7 +34,8 @@
<ui:include src="conversations.xhtml" />
</div>
</div>
- <div id="footer">Created with Groovy, JBoss Seam, and
Facelets</div>
+ <div id="footer">Created with JBoss Seam, EJB 3, JSF 2 and Hibernate
4</div>
</div>
-</h:body>
-</h:html>
+</body>
+</html>
+</f:view>