diff --git a/samples/tutorial/src/main/java/bigbank/Account.java b/samples/tutorial/src/main/java/bigbank/Account.java
new file mode 100644
index 0000000000..1fdc1044e5
--- /dev/null
+++ b/samples/tutorial/src/main/java/bigbank/Account.java
@@ -0,0 +1,51 @@
+package bigbank;
+
+/**
+ * Note this class does not represent best practice, as we are failing to
+ * encapsulate business logic (methods) and state in the domain object.
+ * Nevertheless, this demo is intended to reflect what people usually do,
+ * as opposed to what they ideally would be doing.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class Account {
+ private long id = -1;
+ private String holder;
+ private double balance;
+
+ public Account(String holder) {
+ super();
+ this.holder = holder;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getHolder() {
+ return holder;
+ }
+
+ public void setHolder(String holder) {
+ this.holder = holder;
+ }
+
+ public double getBalance() {
+ return balance;
+ }
+
+ public void setBalance(double balance) {
+ this.balance = balance;
+ }
+
+ public String toString() {
+ return "Account[id=" + id + ",balance=" + balance +",holder=" + holder + "]";
+ }
+
+
+}
diff --git a/samples/tutorial/src/main/java/bigbank/BankDao.java b/samples/tutorial/src/main/java/bigbank/BankDao.java
new file mode 100644
index 0000000000..67806a7e76
--- /dev/null
+++ b/samples/tutorial/src/main/java/bigbank/BankDao.java
@@ -0,0 +1,7 @@
+package bigbank;
+
+public interface BankDao {
+ public Account readAccount(Long id);
+ public void createOrUpdateAccount(Account account);
+ public Account[] findAccounts();
+}
diff --git a/samples/tutorial/src/main/java/bigbank/BankDaoStub.java b/samples/tutorial/src/main/java/bigbank/BankDaoStub.java
new file mode 100644
index 0000000000..de46d38af9
--- /dev/null
+++ b/samples/tutorial/src/main/java/bigbank/BankDaoStub.java
@@ -0,0 +1,32 @@
+package bigbank;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class BankDaoStub implements BankDao {
+ private long id = 0;
+ private Map accounts = new HashMap();
+
+ public void createOrUpdateAccount(Account account) {
+ if (account.getId() == -1) {
+ id++;
+ account.setId(id);
+ }
+ accounts.put(new Long(account.getId()), account);
+ System.out.println("SAVE: " + account);
+ }
+
+ public Account[] findAccounts() {
+ Account[] a = (Account[]) accounts.values().toArray(new Account[] {});
+ System.out.println("Returning " + a.length + " account(s):");
+ for (int i = 0; i < a.length; i++) {
+ System.out.println(" > " + a[i]);
+ }
+ return a;
+ }
+
+ public Account readAccount(Long id) {
+ return (Account) accounts.get(id);
+ }
+
+}
diff --git a/samples/tutorial/src/main/java/bigbank/BankService.java b/samples/tutorial/src/main/java/bigbank/BankService.java
new file mode 100644
index 0000000000..dfbf60f0ba
--- /dev/null
+++ b/samples/tutorial/src/main/java/bigbank/BankService.java
@@ -0,0 +1,15 @@
+package bigbank;
+
+import org.springframework.security.annotation.Secured;
+
+public interface BankService {
+
+ @Secured("IS_AUTHENTICATED_REMEMBERED")
+ public Account readAccount(Long id);
+
+ @Secured("IS_AUTHENTICATED_REMEMBERED")
+ public Account[] findAccounts();
+
+ @Secured("ROLE_TELLER")
+ public Account post(Account account, double amount);
+}
diff --git a/samples/tutorial/src/main/java/bigbank/BankServiceImpl.java b/samples/tutorial/src/main/java/bigbank/BankServiceImpl.java
new file mode 100644
index 0000000000..f33f52e7ab
--- /dev/null
+++ b/samples/tutorial/src/main/java/bigbank/BankServiceImpl.java
@@ -0,0 +1,35 @@
+package bigbank;
+
+import org.springframework.util.Assert;
+
+public class BankServiceImpl implements BankService {
+ private BankDao bankDao;
+
+ public BankServiceImpl(BankDao bankDao) {
+ Assert.notNull(bankDao);
+ this.bankDao = bankDao;
+ }
+
+ public Account[] findAccounts() {
+ return this.bankDao.findAccounts();
+ }
+
+ public Account post(Account account, double amount) {
+ Assert.notNull(account);
+ Assert.notNull(account.getId());
+
+ // We read account bank from DAO so it reflects the latest balance
+ Account a = bankDao.readAccount(account.getId());
+ if (account == null) {
+ throw new IllegalArgumentException("Couldn't find requested account");
+ }
+
+ a.setBalance(a.getBalance() + amount);
+ bankDao.createOrUpdateAccount(a);
+ return a;
+ }
+
+ public Account readAccount(Long id) {
+ return bankDao.readAccount(id);
+ }
+}
diff --git a/samples/tutorial/src/main/java/bigbank/SeedData.java b/samples/tutorial/src/main/java/bigbank/SeedData.java
new file mode 100644
index 0000000000..5bf0774448
--- /dev/null
+++ b/samples/tutorial/src/main/java/bigbank/SeedData.java
@@ -0,0 +1,21 @@
+package bigbank;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.Assert;
+
+public class SeedData implements InitializingBean{
+ private BankDao bankDao;
+
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(bankDao);
+ bankDao.createOrUpdateAccount(new Account("rod"));
+ bankDao.createOrUpdateAccount(new Account("dianne"));
+ bankDao.createOrUpdateAccount(new Account("scott"));
+ bankDao.createOrUpdateAccount(new Account("peter"));
+ }
+
+ public void setBankDao(BankDao bankDao) {
+ this.bankDao = bankDao;
+ }
+
+}
diff --git a/samples/tutorial/src/main/java/bigbank/web/ListAccounts.java b/samples/tutorial/src/main/java/bigbank/web/ListAccounts.java
new file mode 100644
index 0000000000..6c2c5b810e
--- /dev/null
+++ b/samples/tutorial/src/main/java/bigbank/web/ListAccounts.java
@@ -0,0 +1,34 @@
+package bigbank.web;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.util.Assert;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.Controller;
+
+import bigbank.BankService;
+
+public class ListAccounts implements Controller {
+
+ private BankService bankService;
+
+ public ListAccounts(BankService bankService) {
+ Assert.notNull(bankService);
+ this.bankService = bankService;
+ }
+
+ public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // Security check (this is unnecessary if Spring Security is performing the authorization)
+// if (request.getUserPrincipal() == null) {
+// response.sendError(HttpServletResponse.SC_FORBIDDEN, "You must login to view the account list");
+// return null;
+// }
+
+ // Actual business logic
+ ModelAndView mav = new ModelAndView("listAccounts");
+ mav.addObject("accounts", bankService.findAccounts());
+ return mav;
+ }
+
+}
diff --git a/samples/tutorial/src/main/java/bigbank/web/PostAccounts.java b/samples/tutorial/src/main/java/bigbank/web/PostAccounts.java
new file mode 100644
index 0000000000..58fb342215
--- /dev/null
+++ b/samples/tutorial/src/main/java/bigbank/web/PostAccounts.java
@@ -0,0 +1,39 @@
+package bigbank.web;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.util.Assert;
+import org.springframework.web.bind.ServletRequestUtils;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.Controller;
+
+import bigbank.Account;
+import bigbank.BankService;
+
+public class PostAccounts implements Controller {
+
+ private BankService bankService;
+
+ public PostAccounts(BankService bankService) {
+ Assert.notNull(bankService);
+ this.bankService = bankService;
+ }
+
+ public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // Security check (this is unnecessary if Spring Security is performing the authorization)
+// if (request.isUserInRole("ROLE_TELLER")) {
+// response.sendError(HttpServletResponse.SC_FORBIDDEN, "You must be a teller to post transactions");
+// return null;
+// }
+
+ // Actual business logic
+ Long id = ServletRequestUtils.getRequiredLongParameter(request, "id");
+ Double amount = ServletRequestUtils.getRequiredDoubleParameter(request, "amount");
+ Account a = bankService.readAccount(id);
+ bankService.post(a, amount);
+
+ return new ModelAndView("redirect:listAccounts.html");
+ }
+
+}
diff --git a/samples/tutorial/src/main/resources/applicationContext-business.xml b/samples/tutorial/src/main/resources/applicationContext-business.xml
new file mode 100644
index 0000000000..09a1edfaa9
--- /dev/null
+++ b/samples/tutorial/src/main/resources/applicationContext-business.xml
@@ -0,0 +1,19 @@
+
+
+
|
+ |
+
+ |
+
+ |
+ + &amount=-20.00">-$20 + &amount=-5.00">-$5 + &amount=5.00">+$5 + &amount=20.00">+$20 + | +