Hi,

I'm a software architect and we have a major project coming where I thought our
dev team should try new things. So I decided to replace Struts (default option
:P) with JSF and Shale. I thought that it would be good when I personally know
the limits of JSF and Shale first before I put them into our proposal.
For this I've written a small app where the user has to input his personal data
in wizard style (dialog) but somehow I cannot go further than the first page
>:( No errors or exceptions or something but the first dialog screen keeps
opened again and again.
I tried to understand what goes on in the Shale's usecases example app (the
login and profile creation is also a dialog) and mostly copy/pasted the
dialog-config.xml, the jsps and backing beans (I couldn't get the usecases
login part to run btw) but with no luck :'(


Then I thought my "lone wolf" time is up and I should go and ask someone smarter
;)

Oh, becaause the upcoming project is a monster I decided to use Tiles aswell and
MyFaces with Tomahawk extensions.

My web.xml looks like this:
<web-app xmlns="http://java.sun.com/xml/ns/j2ee";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"; version="2.4" id="WebApp_ID">
        <display-name>JSFTest</display-name>
        <!--context-param>
                <description>
                        Comma separated list of URIs of (additional) faces 
config files. 
                        (e.g. /WEB-INF/my-config.xml)
                        See JSF 1.0 PRD2, 10.3.2
                        Attention: You do not have to put 
/WEB-INF/faces-config.xml in here.
                </description>
                <param-name>javax.faces.CONFIG_FILES</param-name>
                
<param-value>/WEB-INF/managed-beans.xml,/WEB-INF/navigation.xml</param-value>
        </context-param-->
        <context-param>
      <param-name>org.apache.commons.chain.CONFIG_WEB_RESOURCE</param-name>
      <param-value>/WEB-INF/chain-config.xml</param-value>
    </context-param>
        <!-- context-param>
      <param-name>org.apache.shale.dialog.CONFIGURATION</param-name>
      <param-value>/WEB-INF/dialog-config.xml</param-value>
    </context-param -->
        <context-param>
                <description>
                        State saving method: "client" or "server" (= default)
                        See JSF Specification 2.5.3
                </description>
                <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
                <param-value>client</param-value>
        </context-param>
        <context-param>
                <description>
                        Only applicable if state saving method is "server" (= 
default).
                        Defines the amount (default = 20) of the latest views 
are stored in session.
                </description>
                
<param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
                <param-value>20</param-value>
        </context-param>
        <context-param>
                <description>
                        Only applicable if state saving method is "server" (= 
default).
                        If true (default) the state will be serialized to a 
byte stream before it
                        is written to the session.
                        If false the state will not be serialized to a byte 
stream.
                </description>
                
<param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
                <param-value>true</param-value>
        </context-param>
        <context-param>
                <description>
                        Only applicable if state saving method is "server" (= 
default) and if
                        org.apache.myfaces.SERIALIZE_STATE_IN_SESSION is true 
(= default)
                        If true (default) the serialized state will be 
compressed before it
                        is written to the session. If false the state will not 
be compressed.
                </description>
                
<param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name>
                <param-value>true</param-value>
        </context-param>
        <context-param>
                <description>
                        This parameter tells MyFaces if javascript code should 
be allowed in the
                        rendered HTML output.
                        If javascript is allowed, command_link anchors will 
have javascript code
                        that submits the corresponding form.
                        If javascript is not allowed, the state saving info and 
nested parameters
                        will be added as url parameters.
                        Default: "true"
                </description>
                <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
                <param-value>false</param-value>
        </context-param>
        <context-param>
                <param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
                <param-value>false</param-value>
        </context-param>
        <context-param>
                <description>
                        If true, rendered HTML code will be formatted, so that 
it is "human
readable".
                        i.e. additional line separators and whitespace will be 
written, that do not
                        influence the HTML code.
                        Default: "true"
                </description>
                <param-name>org.apache.myfaces.PRETTY_HTML</param-name>
                <param-value>true</param-value>
        </context-param>
        <context-param>
                <description>
                        If true, a javascript function will be rendered that is 
able to restore the
                        former vertical scroll on every request. Convenient 
feature if you have
pages
                        with long lists and you do not want the browser page to 
always jump to the
top
                        if you trigger a link or button action that stays on 
the same page.
                        Default: "false"
                </description>
                <param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
                <param-value>true</param-value>
        </context-param>
        <!--context-param>
                <description>
                        Used for encrypting view state.  Only relevant for 
client side
                        state saving.  See MyFaces wiki/web site documentation 
for instructions
                        on how to configure an application for diffenent 
encryption strengths.
                </description>
                <param-name>org.apache.myfaces.secret</param-name>
                <param-value>NzY1NDMyMTA=</param-value>
        </context-param-->
        <context-param>
                <description> 
                        Validate managed beans and navigation rules.
                </description>
                <param-name>org.apache.myfaces.validate</param-name>
                <param-value>true</param-value>
        </context-param>
        <!-- Tiles ViewHandler config file -->
        <context-param>
                <description>
                        Tiles configuration
                        definition files and a listener need to be defined.
                        the listener will initialize JspTilesViewHandlerImpl 
with tiles definitions.
                </description>
                <param-name>tiles-definitions</param-name>
                <param-value>/WEB-INF/tiles-defs.xml</param-value>
        </context-param>
        <servlet>
                <servlet-name>FacesServlet</servlet-name>
                <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
                <load-on-startup>1</load-on-startup>
        </servlet>
        <!-- Shale Application Controller Filter -->
        <filter>
                <filter-name>shale</filter-name>
                
<filter-class>org.apache.shale.faces.ShaleApplicationFilter</filter-class>
        </filter>
        <!-- Tomahawk extension -->
        <filter>
                <filter-name>extensionsFilter</filter-name>
                
<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
                <init-param>
                        <description>
                                Set the size limit for uploaded files. 
                                 Format: 10 - 10 bytes
                                                          10k - 10 KB
                                                          10m - 10 MB
                                                          1g - 1 GB
                        </description>
                        <param-name>uploadMaxFileSize</param-name>
                        <param-value>100m</param-value>
                </init-param>
                <init-param>
                        <description>
                                Set the threshold size - files
                                below this limit are stored in memory, files 
above
                                this limit are stored on disk.
                                Format: 10 - 10 bytes
                                                         10k - 10 KB
                                                         10m - 10 MB
                                                         1g - 1 GB
                        </description>
                        <param-name>uploadThresholdSize</param-name>
                        <param-value>100k</param-value>
                </init-param>
        </filter>
        <filter-mapping>
                <filter-name>extensionsFilter</filter-name>
                <url-pattern>*.jsf</url-pattern>
        </filter-mapping>
        <filter-mapping>
                <filter-name>extensionsFilter</filter-name>
                <url-pattern>/faces/*</url-pattern>
        </filter-mapping>
        <filter-mapping>
                <filter-name>shale</filter-name>
                <url-pattern>/*</url-pattern>
        </filter-mapping>
        <listener>
                
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
        </listener>
        <listener>
                
<listener-class>org.apache.commons.chain.web.ChainListener</listener-class>
        </listener>
        <servlet-mapping>
          <servlet-name>FacesServlet</servlet-name>
          <url-pattern>*.jsf</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
          <servlet-name>FacesServlet</servlet-name>
          <url-pattern>*.faces</url-pattern>
        </servlet-mapping>
        <welcome-file-list>
          <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
</web-app>


And my dialog-config looks like this
<!DOCTYPE dialogs PUBLIC "-//Apache Software Foundation//DTD Shale Dialog
Configuration 1.0//EN"
  "http://struts.apache.org/dtds/shale-dialog-config_1_0.dtd";>
<dialogs>
        <dialog name="Edit Person" start="Setup">
                <!-- Global transition definitions -->
                <transition outcome="cancel" target="Cancel"/>
                <transition outcome="finish" target="Finish"/>
                <action name="Setup" method="#{personActions.setup}">
                        <transition outcome="success" target="Page 1"/>
                </action>
                <view name="Page 1" viewId="/editPerson.jsp">
                        <transition outcome="next" target="Page 2"/>
                </view>
                <view name="Page 2" viewId="/editPerson1.jsp">
                        <transition outcome="next" target="Page 3"/>
                        <transition outcome="previous" target="Page 1"/>
                </view>
                <view name="Page 3" viewId="/editPerson2.jsp">
                        <transition outcome="previous" target="Page 2"/>
                </view>

                <action name="Cancel" method="#{personActions.cancel}">
                        <transition outcome="success" target="Exit"/>
                </action>
                <action name="Finish" method="#{personActions.finish}">
                        <transition outcome="name" target="Page 1"/>
                        <transition outcome="success" target="Exit"/>
                        <transition outcome="contact" target="Page 2"/>
                </action>
                <end name="Exit" viewId="/listPersons.jsp"/>
        </dialog>
</dialogs>

The Page 1 view keeps coming up every time when I click Next

editPerson.jsp  looks like this
<%@ taglib uri="http://java.sun.com/jsf/html"; prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core"; prefix="f" %>
<%@ taglib uri="http://myfaces.apache.org/tomahawk"; prefix="t" %>
<%@ taglib uri="http://struts.apache.org/shale/core"; prefix="s" %>
<f:view>
<h:form id="editPersonForm">
        <h:panelGrid columns="2">
                <h:outputText value="First name:" />
                <h:inputText id="firstName" value="#{personBean.firstName}" />
                <h:outputText value="Last name:" />
                <h:inputText id="lastName" value="#{personBean.lastName}" />
                <h:outputText value="Title" />
                <h:inputText id="titleName" value="#{personBean.title}" />
                <h:outputText value="Date of birth:" />
                <t:inputDate id="dateOfBirth"
                                popupCalendar="false"
                                type="date"
                                value="#{personBean.dateOfBirth}" />
        </h:panelGrid>
        <s:token id="token"/>
        <h:panelGrid columns="4">
        <h:commandButton
                                id="previous"
                action="previous"
                disabled="true"
                value="<<< Previous page"/>
        <h:commandButton
                        id="next"
                action="next"
                value="Next page >>>"/>
        <h:commandButton
                                id="finish"
                action="finish"
                value="Finish"/>
        <h:commandButton
                                id="cancel"
                action="cancel"
                immediate="true"
                value="Cancel"/>
        </h:panelGrid>
        <h:message for="token"/>
</h:form>
</f:view>

and faces-config.xml
<faces-config>
        <application>
                
<view-handler>org.apache.myfaces.tomahawk.application.jsp.JspTilesViewHandlerImpl</view-handler>
        </application>
        <application>
          <locale-config>
            <default-locale>ee_ET</default-locale>
            <supported-locale>ee</supported-locale>
            <supported-locale>en</supported-locale>
          </locale-config>
        </application>
        <navigation-rule>
                <from-view-id>/listPersons.jsp</from-view-id>
                <!-- navigation-case>
                        <from-outcome>edit</from-outcome>
                        <to-view-id>/editPerson.jsp</to-view-id>
                </navigation-case-->
                <navigation-case>
                        <from-outcome>remove</from-outcome>
                        <to-view-id>/removePerson.jsp</to-view-id>
                </navigation-case>
                <!-- navigation-case>
                        <from-outcome>change</from-outcome>
                        <to-view-id>/editPerson.jsp</to-view-id>
                </navigation-case-->
        </navigation-rule>
        <managed-bean>
                <managed-bean-name>personDataBean</managed-bean-name>
                
<managed-bean-class>jsftest.beans.PersonBean</managed-bean-class>
                <managed-bean-scope>request</managed-bean-scope>
        </managed-bean>
        <managed-bean>
                <managed-bean-name>personActions</managed-bean-name>
                
<managed-bean-class>jsftest.faceforms.PersonBeanActions</managed-bean-class>
                <managed-bean-scope>request</managed-bean-scope>
        </managed-bean>
</faces-config>

and the PersonBeanAction's most interesting methods look like this

    public String setup() {
        log.info("PersonBeanAction is setting up");
        // Configure a state object
        PersonBean state = new PersonBean();
        state.setCreating(true);
        // Register our state as the data object for this dialog, and continue
        setValue("#{dialog.data}", state);
        log.info("set up complete");
        return SUCCESS;
    }

    public String finish() {
        // Acquire our state information
        PersonBean state = (PersonBean) getValue("#{dialog.data}");
        boolean okFirstName = true;
        boolean okLastName = true;
        boolean okTelNo = true;
        // Validate required fields if creating
        if (state.isCreating()) {
            if ((state.getFirstName() == null) || (state.getFirstName().length()
< 1)) {
                error(messages.getMessage("profile.firstName"));
                okFirstName = false;
            }
            if ((state.getLastName() == null) || (state.getLastName().length() <
1)) {
                error(messages.getMessage("profile.lastName"));
                okLastName = false;
            }
            if (state.getEmployment().size() > 0) {
                boolean contactFound = false;
                for (Iterator it = state.getEmployment().iterator(); 
it.hasNext();)
{
                        Employer emp = (Employer) it.next();
                        if (emp.getEmails().size() > 0 || 
emp.getPhoneNos().size() > 0) {
                                contactFound = true;
                                break;
                        }
                }
                if (!contactFound) {
                        error(messages.getMessage("profile.contact"));
                        okTelNo = false;
                }
            } else {
                error(messages.getMessage("profile.contact"));
                okTelNo = false;
            }
        }
        // Return appropriate outcome on validation failures
        if (!okFirstName || !okLastName) {
                log.info("PersonBeanAction finished with error (no first or last
name)");
            return NAME;
        } else if (!okTelNo) {
                log.info("PersonBeanAction finished with error (no contacts)");
            return CONTACT;
        }
        // Return a success outcome
        log.info("PersonBeanAction finished successfully");
        return SUCCESS;
    }

Has anyone have a glue where I screw up?

I allready downloaded Shale's source and found out that the "next" transition
won't get posted to DialogNavigationHandler class by remotely debugging my app.
Why ?

S.O.S !!!

rgds Sander

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to