Moved Spring Web Flow to a top level project
This commit is contained in:
33
spring-webflow-samples/numberguess/src/etc/filter.properties
Normal file
33
spring-webflow-samples/numberguess/src/etc/filter.properties
Normal file
@@ -0,0 +1,33 @@
|
||||
# $Header$
|
||||
|
||||
# Contains filterable project settings. Setting placeholders in filterable project text
|
||||
# files will be replaced with these values when the 'statics' build target is run.
|
||||
#
|
||||
# You may add static settings directly to this source file in the format:
|
||||
# setting=value e.g MY_SETTING=myvalue
|
||||
# This is appropriate usage if you know the setting value will never change.
|
||||
#
|
||||
# At build time this source file is copied to the ${target.dir} where additional
|
||||
# dynamic settings may be appended using the <propertyfile> task. Use this approach
|
||||
# when a setting value depends on the build or the local user's environment.
|
||||
#
|
||||
# An example of this approach is shown below:
|
||||
#
|
||||
# build.xml
|
||||
# <target name="build.prepare" depends="common-targets.build.prepare">
|
||||
# <!-- Append additional local settings that are applicable to this project -->
|
||||
# <propertyfile file="${target.filter.file}">
|
||||
# <!-- key=the name of the setting
|
||||
# value=the property in your build.properties file that has the local setting value -->
|
||||
# <entry key="MY_LOCAL_SETTING" value="${my.local.setting}" />
|
||||
# </propertyfile>
|
||||
# </target>
|
||||
#
|
||||
# This allows for dynamic replacement values that are sourced from local properties files to facilitate
|
||||
# local user settings.
|
||||
#
|
||||
# To refer to filterable settings within project source files like config files, JSPs, or
|
||||
# other text files use the standard ant placeholder format:
|
||||
# @SETTING_NAME@ e.g, @MY_SETTING@ and @MY_LOCAL_SETTING@
|
||||
#
|
||||
# Your settings:
|
||||
@@ -0,0 +1,20 @@
|
||||
log4j.rootCategory=WARN, stdout, logfile
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
|
||||
log4j.appender.logfile.File=${@PROJECT_WEBAPP_NAME@.root}/@PROJECT_WEBAPP_NAME@.log
|
||||
log4j.appender.logfile.MaxFileSize=512KB
|
||||
|
||||
# Keep three backup files
|
||||
log4j.appender.logfile.MaxBackupIndex=3
|
||||
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
|
||||
|
||||
#Pattern to output : date priority [category] - <message>line_separator
|
||||
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
#Enable webflow debug logging
|
||||
log4j.category.org.springframework.webflow=DEBUG
|
||||
log4j.category.org.springframework.binding=DEBUG
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.webflow.samples.numberguess;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Calendar;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Action that encapsulates logic for the number guess sample flow. Note that
|
||||
* this is a stateful action: it holds modifiable state in instance members!
|
||||
*
|
||||
* @author Erwin Vervaet
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class HigherLowerGame implements Serializable {
|
||||
|
||||
private static final Random random = new Random();
|
||||
|
||||
private Calendar start = Calendar.getInstance();
|
||||
|
||||
private int answer = random.nextInt(101);
|
||||
|
||||
private int guesses = 0;
|
||||
|
||||
private GuessResult result;
|
||||
|
||||
public int getAnswer() {
|
||||
return answer;
|
||||
}
|
||||
|
||||
public int getGuesses() {
|
||||
return guesses;
|
||||
}
|
||||
|
||||
public GuessResult getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(GuessResult result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
Calendar now = Calendar.getInstance();
|
||||
long durationMilliseconds = now.getTime().getTime() - start.getTime().getTime();
|
||||
return durationMilliseconds / 1000;
|
||||
}
|
||||
|
||||
public GuessResult makeGuess(int guess) {
|
||||
if (guess < 0 || guess > 100) {
|
||||
setResult(GuessResult.INVALID);
|
||||
}
|
||||
else {
|
||||
guesses++;
|
||||
if (answer < guess) {
|
||||
setResult(GuessResult.TOO_HIGH);
|
||||
}
|
||||
else if (answer > guess) {
|
||||
setResult(GuessResult.TOO_LOW);
|
||||
}
|
||||
else {
|
||||
setResult(GuessResult.CORRECT);
|
||||
}
|
||||
}
|
||||
return getResult();
|
||||
}
|
||||
|
||||
enum GuessResult {
|
||||
TOO_HIGH, TOO_LOW, CORRECT, INVALID
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.webflow.samples.numberguess;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Action that encapsulates logic for the number guess sample flow.
|
||||
*
|
||||
* @author Keri Donald
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class MastermindGame implements Serializable {
|
||||
|
||||
private GameData data = new GameData();
|
||||
|
||||
public GameData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public Collection getGuessHistory() {
|
||||
return data.getGuessHistory();
|
||||
}
|
||||
|
||||
public GuessResult getResult() {
|
||||
return data.getLastGuessResult();
|
||||
}
|
||||
|
||||
public void setResult(GuessResult result) {
|
||||
data.setLastGuessResult(result);
|
||||
}
|
||||
|
||||
public GuessResult makeGuess(String guess) {
|
||||
if (isGuessValid(guess)) {
|
||||
setResult(calculateResult(guess));
|
||||
}
|
||||
else {
|
||||
setResult(GuessResult.INVALID);
|
||||
}
|
||||
return getResult();
|
||||
}
|
||||
|
||||
private boolean isGuessValid(String guess) {
|
||||
if (guess == null || guess.length() != 4) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!Character.isDigit(guess.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
int digit = Character.getNumericValue(guess.charAt(i));
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (digit == Character.getNumericValue(guess.charAt(j))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private GuessResult calculateResult(String guess) {
|
||||
int rightPosition = 0;
|
||||
int correctButWrongPosition = 0;
|
||||
for (int i = 0; i < guess.length(); i++) {
|
||||
char digit = guess.charAt(i);
|
||||
for (int j = 0; j < data.answer.length(); j++) {
|
||||
char answerDigit = data.answer.charAt(j);
|
||||
if (digit == answerDigit) {
|
||||
if (i == j) {
|
||||
rightPosition++;
|
||||
}
|
||||
else {
|
||||
correctButWrongPosition++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
data.recordGuessData(guess, rightPosition, correctButWrongPosition);
|
||||
if (rightPosition == 4) {
|
||||
return GuessResult.CORRECT;
|
||||
}
|
||||
else {
|
||||
return GuessResult.WRONG;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple data holder for number guess info.
|
||||
*/
|
||||
public static class GameData implements Serializable {
|
||||
|
||||
private static Random random = new Random();
|
||||
|
||||
private Calendar start = Calendar.getInstance();
|
||||
|
||||
private String answer;
|
||||
|
||||
private List<GuessData> guessHistory = new ArrayList<GuessData>();
|
||||
|
||||
private GuessResult lastGuessResult;
|
||||
|
||||
// property accessors for JSTL EL
|
||||
|
||||
public GameData() {
|
||||
this.answer = createAnswer();
|
||||
}
|
||||
|
||||
public int getGuesses() {
|
||||
return guessHistory.size();
|
||||
}
|
||||
|
||||
public GuessResult getLastGuessResult() {
|
||||
return lastGuessResult;
|
||||
}
|
||||
|
||||
public void setLastGuessResult(GuessResult lastGuessResult) {
|
||||
this.lastGuessResult = lastGuessResult;
|
||||
}
|
||||
|
||||
public String getAnswer() {
|
||||
return answer;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
Calendar now = Calendar.getInstance();
|
||||
long durationMilliseconds = now.getTime().getTime() - start.getTime().getTime();
|
||||
return durationMilliseconds / 1000;
|
||||
}
|
||||
|
||||
public Collection<GuessData> getGuessHistory() {
|
||||
return guessHistory;
|
||||
}
|
||||
|
||||
public GuessData getLastGuessData() {
|
||||
if (guessHistory.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return guessHistory.get(guessHistory.size() - 1);
|
||||
}
|
||||
|
||||
public void recordGuessData(String guess, int rightPosition, int correctButWrongPosition) {
|
||||
guessHistory.add(new GuessData(guess, rightPosition, correctButWrongPosition));
|
||||
}
|
||||
|
||||
public String createAnswer() {
|
||||
StringBuffer buffer = new StringBuffer(4);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int digit = random.nextInt(10);
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (digit == Character.getNumericValue(buffer.charAt(j))) {
|
||||
j = -1;
|
||||
digit = random.nextInt(10);
|
||||
}
|
||||
}
|
||||
buffer.append(digit);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public class GuessData implements Serializable {
|
||||
private String guess;
|
||||
|
||||
private int rightPosition;
|
||||
|
||||
private int correctButWrongPosition;
|
||||
|
||||
public GuessData(String guess, int rightPosition, int correctButWrongPosition) {
|
||||
this.guess = guess;
|
||||
this.rightPosition = rightPosition;
|
||||
this.correctButWrongPosition = correctButWrongPosition;
|
||||
}
|
||||
|
||||
public int getCorrectButWrongPosition() {
|
||||
return correctButWrongPosition;
|
||||
}
|
||||
|
||||
public String getGuess() {
|
||||
return guess;
|
||||
}
|
||||
|
||||
public int getRightPosition() {
|
||||
return rightPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum GuessResult {
|
||||
WRONG, CORRECT, INVALID
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
log4j.rootCategory=WARN, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
# Enable web flow logging
|
||||
log4j.category.org.springframework.webflow=DEBUG
|
||||
log4j.category.org.springframework.binding=DEBUG
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:flow="http://www.springframework.org/schema/webflow-config"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd">
|
||||
|
||||
<!--
|
||||
Exposes web flows for execution at a single request URL.
|
||||
The id of a flow to launch should be passed in by clients using
|
||||
the "_flowId" request parameter:
|
||||
e.g. /play.htm?_flowId=mastermind
|
||||
-->
|
||||
<bean name="/play.htm" class="org.springframework.webflow.executor.mvc.FlowController">
|
||||
<property name="flowExecutor" ref="flowExecutor" />
|
||||
</bean>
|
||||
|
||||
<!-- Launches new flow executions and resumes existing executions. -->
|
||||
<flow:executor id="flowExecutor" registry-ref="flowRegistry" repository-type="singlekey"/>
|
||||
|
||||
<!-- Creates the registry of flow definitions for this application -->
|
||||
<flow:registry id="flowRegistry">
|
||||
<flow:location path="/WEB-INF/higherlower.xml" />
|
||||
<flow:location path="/WEB-INF/mastermind.xml" />
|
||||
</flow:registry>
|
||||
|
||||
<!-- Resolves flow view names to .jsp templates -->
|
||||
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
|
||||
<property name="prefix" value="/WEB-INF/jsp/" />
|
||||
<property name="suffix" value=".jsp" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow xmlns="http://www.springframework.org/schema/webflow"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/webflow
|
||||
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">
|
||||
|
||||
<var name="game" class="org.springframework.webflow.samples.numberguess.HigherLowerGame"/>
|
||||
|
||||
<start-state idref="enterGuess"/>
|
||||
|
||||
<view-state id="enterGuess" view="higherlower.enterGuess">
|
||||
<transition on="submit" to="makeGuess"/>
|
||||
</view-state>
|
||||
|
||||
<action-state id="makeGuess">
|
||||
<evaluate-action expression="flowScope.game.makeGuess(requestParameters.guess)">
|
||||
<evaluation-result name="guessResult"/>
|
||||
</evaluate-action>
|
||||
<transition on="CORRECT" to="showAnswer"/>
|
||||
<transition on="*" to="enterGuess"/>
|
||||
<transition on-exception="java.lang.NumberFormatException" to="enterGuess"/>
|
||||
</action-state>
|
||||
|
||||
<end-state id="showAnswer" view="higherlower.showAnswer"/>
|
||||
|
||||
</flow>
|
||||
@@ -0,0 +1,34 @@
|
||||
<%@ include file="includeTop.jsp" %>
|
||||
|
||||
<div id="content">
|
||||
<div id="insert"><img src="images/webflow-logo.jpg"/></div>
|
||||
<h2>The Number Guess Game</h2>
|
||||
<h3>Guess a number between 0 and 100!</h3>
|
||||
<hr>
|
||||
<form name="guessForm" method="post">
|
||||
<table>
|
||||
<tr class="readOnly">
|
||||
<td>Number of guesses:</td>
|
||||
<td><b>${game.guesses}</b></td>
|
||||
</tr>
|
||||
<tr class="readOnly">
|
||||
<td>Your last guess was:</td>
|
||||
<td><b><i>${game.result}</i></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Guess:</td>
|
||||
<td>
|
||||
<input type="text" name="guess" value="${param.guess}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="buttonBar">
|
||||
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}">
|
||||
<input type="submit" class="button" name="_eventId_submit" value="Guess">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<%@ include file="includeBottom.jsp" %>
|
||||
@@ -0,0 +1,29 @@
|
||||
<%@ include file="includeTop.jsp" %>
|
||||
|
||||
<div id="content">
|
||||
<div id="insert"><img src="images/webflow-logo.jpg"/></div>
|
||||
<h2>You guessed it!</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Answer:</td>
|
||||
<td>${game.answer}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total number of guesses:</td>
|
||||
<td>${game.guesses}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Elapsed time in seconds:</td>
|
||||
<td>${game.duration}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="buttonBar">
|
||||
<form action="play.htm">
|
||||
<input type="hidden" name="_flowId" value="higherlower">
|
||||
<input type="submit" value="Play Again!">
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<%@ include file="includeBottom.jsp" %>
|
||||
@@ -0,0 +1,5 @@
|
||||
<div id="copyright">
|
||||
<p>© Copyright 2002-2006, <a href="http://www.springframework.org">www.springframework.org</a>, under the terms of the Apache 2.0 software license.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,21 @@
|
||||
<%@ page contentType="text/html" %>
|
||||
<%@ page session="false" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
|
||||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Play a game</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="logo">
|
||||
<img src="images/spring-logo.jpg" alt="Logo">
|
||||
</div>
|
||||
|
||||
<div id="navigation">
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,34 @@
|
||||
<%@ include file="includeTop.jsp" %>
|
||||
|
||||
<div id="content">
|
||||
<div id="insert"><img src="images/webflow-logo.jpg"/></div>
|
||||
<h2>Mastermind</h2>
|
||||
<h3>Guess a four digit number!</h3>
|
||||
<hr>
|
||||
<p>Note: each guess must be 4 unique digits!</p>
|
||||
<p>Number of guesses so far: ${game.data.guesses}</p>
|
||||
|
||||
<%@include file="mastermind.guessHistoryTable.jsp" %>
|
||||
|
||||
<form name="guessForm" method="post">
|
||||
<c:if test="${game.result == 'INVALID'}">
|
||||
<div class="error">Your guess was invalid: it must be a 4 digit number (e.g 1234), and each digit must be unique.</div>
|
||||
</c:if>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Guess:</td>
|
||||
<td align="left">
|
||||
<input type="text" name="guess" value="${param.guess}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="buttonBar">
|
||||
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}">
|
||||
<input type="submit" class="button" name="_eventId_submit" value="Guess">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<%@ include file="includeBottom.jsp" %>
|
||||
@@ -0,0 +1,15 @@
|
||||
<c:if test="${!empty game.guessHistory}">
|
||||
<h4>Guess history:</h4>
|
||||
<table border="1">
|
||||
<th>Guess</th>
|
||||
<th>Right Position</th>
|
||||
<th>Present But Wrong Position</th>
|
||||
<c:forEach var="guessData" items="${game.guessHistory}">
|
||||
<tr>
|
||||
<td>${guessData.guess}</td>
|
||||
<td>${guessData.rightPosition}</td>
|
||||
<td>${guessData.correctButWrongPosition}</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</table>
|
||||
</c:if>
|
||||
@@ -0,0 +1,28 @@
|
||||
<%@ include file="includeTop.jsp" %>
|
||||
|
||||
<div id="content">
|
||||
<div id="insert"><img src="images/webflow-logo.jpg"/></div>
|
||||
<h2>Show answer</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Total number of guesses:</td>
|
||||
<td>${game.data.guesses}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Elapsed time in seconds:</td>
|
||||
<td>${game.data.duration}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Answer:</td>
|
||||
<td>${game.data.answer}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="buttonBar">
|
||||
<form action="play.htm">
|
||||
<input type="hidden" name="_flowId" value="mastermind">
|
||||
<input type="submit" value="Play Again!">
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<%@ include file="includeBottom.jsp" %>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow xmlns="http://www.springframework.org/schema/webflow"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/webflow
|
||||
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">
|
||||
|
||||
<var name="game" class="org.springframework.webflow.samples.numberguess.MastermindGame"/>
|
||||
|
||||
<start-state idref="enterGuess"/>
|
||||
|
||||
<view-state id="enterGuess" view="mastermind.enterGuess">
|
||||
<transition on="submit" to="makeGuess"/>
|
||||
</view-state>
|
||||
|
||||
<action-state id="makeGuess">
|
||||
<evaluate-action expression="flowScope.game.makeGuess(requestParameters.guess)">
|
||||
<evaluation-result name="guessResult"/>
|
||||
</evaluate-action>
|
||||
<transition on="CORRECT" to="showAnswer"/>
|
||||
<transition on="*" to="enterGuess"/>
|
||||
</action-state>
|
||||
|
||||
<end-state id="showAnswer" view="mastermind.showAnswer"/>
|
||||
|
||||
</flow>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<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">
|
||||
|
||||
<servlet>
|
||||
<servlet-name>numberguess</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
|
||||
</init-param>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>numberguess</servlet-name>
|
||||
<url-pattern>*.htm</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
</web-app>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<DIV align="left">Number Guess - A Spring Web Flow Sample</DIV>
|
||||
<HR>
|
||||
This Spring Web Flow (SWF) sample application illustrates:
|
||||
<ul>
|
||||
<li>
|
||||
Use of stateful middle-tier components to carry out the execution of game business logic. It shows how to use SWF to
|
||||
develop such components without coupling your application code to SWF APIs.
|
||||
</li>
|
||||
<li>
|
||||
Use of custom state exception handlers to handle exceptions.
|
||||
</li>
|
||||
<li>
|
||||
Use of the evaluate-action to evaluate expressions against the flow request context;
|
||||
in this example to call the "makeGuess" method on a flow-scoped "game" bean.
|
||||
</li>
|
||||
</ul>
|
||||
<DIV align="left">
|
||||
<P>
|
||||
<A href="play.htm?_flowId=higherlower">Play Higher or Lower</A>
|
||||
</P>
|
||||
<p>
|
||||
The well known higher-or-lower number guess sample app.
|
||||
</p>
|
||||
</DIV>
|
||||
<DIV align="left">
|
||||
<P>
|
||||
<A href="play.htm?_flowId=mastermind">Play Mastermind</A>
|
||||
</P>
|
||||
<P>
|
||||
Figure out the 4 digit number - a fun mindteaser sample app.
|
||||
</P>
|
||||
</DIV>
|
||||
<HR>
|
||||
</BODY>
|
||||
</HTML>
|
||||
58
spring-webflow-samples/numberguess/src/main/webapp/style.css
Normal file
58
spring-webflow-samples/numberguess/src/main/webapp/style.css
Normal file
@@ -0,0 +1,58 @@
|
||||
body {
|
||||
width: 720px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
div#logo {
|
||||
width: 720px;
|
||||
height: 73px;
|
||||
background: #86AEA5;
|
||||
}
|
||||
|
||||
div#navigation {
|
||||
width: 720px;
|
||||
height: 15px;
|
||||
background: #E2F3B8;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div#content {
|
||||
width: 720px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div#insert {
|
||||
width: 120;
|
||||
float: right;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.buttonBar {
|
||||
height: 1.5em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div#copyright {
|
||||
width: 720px;
|
||||
}
|
||||
|
||||
div#copyright p {
|
||||
text-align: center;
|
||||
font-family: Tahoma, sans-serif;
|
||||
font-size: 75%;
|
||||
color: div#336633;
|
||||
margin-left: 5px;
|
||||
font-weight: bold;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.readOnly {
|
||||
color: rgb(192, 192, 192);
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.webflow.samples.numberguess;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.webflow.samples.numberguess.MastermindGame.GameData;
|
||||
import org.springframework.webflow.samples.numberguess.MastermindGame.GuessResult;
|
||||
|
||||
public class MastermindGameTests extends TestCase {
|
||||
|
||||
private MastermindGame action = new MastermindGame();
|
||||
|
||||
protected void setUp() {
|
||||
action = new MastermindGame();
|
||||
}
|
||||
|
||||
public void testGuessNoInputProvided() throws Exception {
|
||||
GuessResult result = action.makeGuess(null);
|
||||
assertEquals(GuessResult.INVALID, result);
|
||||
}
|
||||
|
||||
public void testGuessInputInvalidLength() throws Exception {
|
||||
GuessResult result = action.makeGuess("123");
|
||||
assertEquals(GuessResult.INVALID, result);
|
||||
}
|
||||
|
||||
public void testGuessInputNotAllDigits() throws Exception {
|
||||
GuessResult result = action.makeGuess("12AB");
|
||||
assertEquals(GuessResult.INVALID, result);
|
||||
}
|
||||
|
||||
public void testGuessInputNotUniqueDigits() throws Exception {
|
||||
GuessResult result = action.makeGuess("1111");
|
||||
assertEquals(GuessResult.INVALID, result);
|
||||
}
|
||||
|
||||
public void testGuessRetry() throws Exception {
|
||||
GuessResult result = action.makeGuess("1234");
|
||||
assertEquals(GuessResult.WRONG, result);
|
||||
}
|
||||
|
||||
public void testGuessCorrect() throws Exception {
|
||||
GuessResult result = action.makeGuess(null);
|
||||
assertEquals(GuessResult.INVALID, result);
|
||||
GameData data = action.getData();
|
||||
result = action.makeGuess(data.getAnswer());
|
||||
assertEquals(GuessResult.CORRECT, result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user