View Javadoc
1   package ejava.examples.ejbsessionbank.web;
2   
3   import java.io.IOException;
4   
5   import java.util.HashMap;
6   import java.util.List;
7   import java.util.Map;
8   import java.util.Properties;
9   
10  import javax.naming.InitialContext;
11  import javax.servlet.RequestDispatcher;
12  import javax.servlet.ServletConfig;
13  import javax.servlet.ServletException;
14  import javax.servlet.http.HttpServlet;
15  import javax.servlet.http.HttpServletRequest;
16  import javax.servlet.http.HttpServletResponse;
17  
18  import org.apache.commons.logging.Log;
19  import org.apache.commons.logging.LogFactory;
20  
21  import ejava.examples.ejbsessionbank.bl.Teller;
22  import ejava.examples.ejbsessionbank.bo.Account;
23  import ejava.examples.ejbsessionbank.bo.Ledger;
24  import ejava.examples.ejbsessionbank.ejb.TellerLocal;
25  import ejava.examples.ejbsessionbank.ejb.TellerRemote;
26  import ejava.util.ejb.EJBClient;
27  import ejava.util.jndi.JNDIUtil;
28  
29  @SuppressWarnings("serial")
30  public class TellerHandlerServlet extends HttpServlet {
31      private static final Log log = LogFactory.getLog(TellerHandlerServlet.class);
32      public static final String COMMAND_PARAM = "command";
33      public static final String EXCEPTION_PARAM = "exception";
34      public static final String HANDLER_TYPE_KEY = "type";
35      public static final String ADMIN_TYPE = "admin";
36      public static final String CREATE_ACCOUNT_COMMAND = "Create Account";
37      public static final String DEPOSIT_COMMAND = "Deposit";
38      public static final String WITHDRAW_COMMAND = "Withdraw";
39      public static final String GET_ACCOUNT_COMMAND = "Get Account";
40      public static final String CLOSE_ACCOUNT_COMMAND = "Close Account";
41      public static final String GET_ACCOUNTS_COMMAND = "Get Accounts";
42      public static final String CREATE_ACCOUNTS_COMMAND = "Create Accounts";
43      public static final String GET_LEDGER_COMMAND = "Get Ledger";
44      public static final String STEAL_ALL_ACCOUNTS_COMMAND = "Steal All Accounts";
45      public static final String jndiName = EJBClient.getRemoteLookupName(
46      	"ejbsessionBankEAR", "ejbsessionBankEJB",  
47      	"TellerEJB", TellerRemote.class.getName());
48      
49      private static final String UNKNOWN_COMMAND_URL = 
50          "/WEB-INF/content/UnknownCommand.jsp";
51      private Map<String, Handler> handlers = new HashMap<String, Handler>();
52      
53      /**
54       * This will get automatically injected when running within the 
55       * application server with the TellerEJB. beanInterface is only
56       * needed to resolve the derived type ambiguity for Local and Remote
57       * caused by the design of our example. 
58       */
59      @javax.ejb.EJB(beanInterface=TellerLocal.class)
60      private Teller injectedTeller;
61  
62      private Properties env=null;
63  
64      /**
65       * Init verify the teller reference to the EJB logic is in place and
66       * initializes the proper handler for the assigned role supplied in 
67       * the servlet init parameters.
68       */
69      public void init() throws ServletException {
70          log.debug("init() called; teller=" + injectedTeller);
71          
72          try {
73              ServletConfig config = getServletConfig();
74              if (injectedTeller==null) { //not running on server, prepare manual lookups
75                  env=JNDIUtil.getJNDIProperties("jboss.remoting.");
76              }
77              
78              //build a list of handlers for individual commands
79              if (ADMIN_TYPE.equals(config.getInitParameter(HANDLER_TYPE_KEY))) {
80                  handlers.put(CREATE_ACCOUNT_COMMAND, new CreateAccount());    
81                  handlers.put(GET_ACCOUNT_COMMAND, new GetAccount());    
82                  handlers.put(CLOSE_ACCOUNT_COMMAND, new CloseAccount());    
83                  handlers.put(DEPOSIT_COMMAND, new DepositAccount());    
84                  handlers.put(WITHDRAW_COMMAND, new WithdrawAccount());    
85                  handlers.put(GET_ACCOUNTS_COMMAND, new GetAccounts());    
86                  handlers.put(CREATE_ACCOUNTS_COMMAND, new CreateAccounts());    
87                  handlers.put(GET_LEDGER_COMMAND, new GetLedger());    
88                  handlers.put(STEAL_ALL_ACCOUNTS_COMMAND, new StealAccounts());    
89              }            
90          }
91          catch (Exception ex) {
92              log.fatal("error initializing handler", ex);
93              throw new ServletException("error initializing handler", ex);
94          }
95      }
96  
97      /**
98       * This is the main dispatch method for the servlet. It expects to
99       * find a command keyed by an argument in the request parameters.
100      */
101     protected void doGet(HttpServletRequest request, 
102                          HttpServletResponse response) 
103         throws ServletException, IOException {
104         log.debug("doGet() called");
105 
106         String command = request.getParameter(COMMAND_PARAM);
107         log.debug("command=" + command);
108 
109         InitialContext jndi = null;
110         Teller teller = injectedTeller; //assign to what was injected
111         try {
112         	if (teller==null) { //not injected -- manually lookup
113         	    jndi=new InitialContext(env);
114      	        teller = (Teller)jndi.lookup(jndiName);
115         	}
116             if (command != null) {
117                 Handler handler = handlers.get(command);
118                 if (handler != null) {
119                     handler.handle(request, response, teller);
120                 }
121                 else {
122                     RequestDispatcher rd = 
123                         getServletContext().getRequestDispatcher(
124                             UNKNOWN_COMMAND_URL);
125                             rd.forward(request, response);
126                 }
127             }
128             else {
129                 throw new Exception("no " + COMMAND_PARAM + " supplied"); 
130             }
131         }
132         catch (Exception ex) {
133             request.setAttribute(EXCEPTION_PARAM, ex);
134             RequestDispatcher rd = getServletContext().getRequestDispatcher(
135                     UNKNOWN_COMMAND_URL);
136                     rd.forward(request, response);
137         } finally {
138         	if (jndi != null) {
139         		try { jndi.close(); } catch (Exception ex){}
140         	}
141         }
142     }
143 
144     /**
145      * Since this is a toy, we don't really care whether they call get or post.
146      */
147     protected void doPost(HttpServletRequest request, 
148                           HttpServletResponse response) 
149         throws ServletException, IOException {
150         log.debug("doPost() called, calling doGet()");
151         doGet(request, response);
152     }
153 
154     public void destroy() {
155         log.debug("destroy() called");
156     }
157     
158     private abstract class Handler {
159         protected static final String MAIN_PAGE = 
160             "/index.jsp";
161         protected static final String DISPLAY_EXCEPTION = 
162             "/WEB-INF/content/DisplayException.jsp";
163         protected static final String ACCT_NUM_PARAM = "accountNumber";
164         protected static final String AMOUNT_PARAM = "amount";
165         protected static final String INDEX_PARAM = "index";
166         protected static final String NEXT_INDEX_PARAM = "nextIndex";
167         protected static final String COUNT_PARAM = "count";
168         protected static final String ACCOUNT_PARAM = "account";
169         protected static final String ACCOUNTS_PARAM = "accounts";
170         protected static final String LEDGER_PARAM = "ledger";
171         protected static final String DISPLAY_ACCOUNT_URL = 
172             "/WEB-INF/content/DisplayAccount.jsp";
173         protected static final String DISPLAY_ACCOUNTS_URL = 
174             "/WEB-INF/content/DisplayAccounts.jsp";
175         protected static final String DISPLAY_LEDGER_URL = 
176             "/WEB-INF/content/DisplayLedger.jsp";
177         public abstract void handle(HttpServletRequest request, 
178                 HttpServletResponse response, Teller t) 
179                 throws ServletException, IOException;
180     }
181     
182     private class CreateAccount extends Handler {
183         public void handle(HttpServletRequest request, 
184                 HttpServletResponse response, Teller t) 
185                 throws ServletException, IOException {
186             try {
187                 String acctNum = (String)request.getParameter(ACCT_NUM_PARAM);                
188                 Account account = t.createAccount(acctNum);
189                 
190                 request.setAttribute(ACCOUNT_PARAM, account);                
191                 RequestDispatcher rd = 
192                   getServletContext().getRequestDispatcher(DISPLAY_ACCOUNT_URL);
193                 rd.forward(request, response);                
194             }
195             catch (Exception ex) {
196                 log.fatal("error creating account:" + ex, ex);
197                 request.setAttribute(EXCEPTION_PARAM, ex);
198                 RequestDispatcher rd = 
199                     getServletContext().getRequestDispatcher(DISPLAY_EXCEPTION);
200                 rd.forward(request, response);                
201             }
202         }
203     }
204 
205     private class GetAccount extends Handler {
206         public void handle(HttpServletRequest request, 
207                 HttpServletResponse response, Teller teller) 
208                 throws ServletException, IOException {
209             try {
210                 String acctNum = (String)request.getParameter(ACCT_NUM_PARAM);                
211                 Account account = teller.getAccount(acctNum);
212                 
213                 request.setAttribute(ACCOUNT_PARAM, account);                
214                 RequestDispatcher rd = 
215                   getServletContext().getRequestDispatcher(DISPLAY_ACCOUNT_URL);
216                 rd.forward(request, response);                
217             }
218             catch (Exception ex) {
219                 log.fatal("error creating account:" + ex, ex);
220                 request.setAttribute(EXCEPTION_PARAM, ex);
221                 RequestDispatcher rd = 
222                     getServletContext().getRequestDispatcher(DISPLAY_EXCEPTION);
223                 rd.forward(request, response);                
224             }
225         }
226     }
227 
228     private class DepositAccount extends Handler {
229         public void handle(HttpServletRequest request, 
230                 HttpServletResponse response, Teller teller) 
231                 throws ServletException, IOException {
232             try {
233                 String acctNum = (String)request.getParameter(ACCT_NUM_PARAM);                
234                 String amountStr = (String)request.getParameter(AMOUNT_PARAM);
235                 double amount = Double.parseDouble(amountStr);
236                 
237                 Account account = teller.getAccount(acctNum);
238                 account.deposit(amount);
239                 teller.updateAccount(account);
240                 
241                 request.setAttribute(ACCOUNT_PARAM, account);                
242                 RequestDispatcher rd = 
243                   getServletContext().getRequestDispatcher(DISPLAY_ACCOUNT_URL);
244                 rd.forward(request, response);                
245             }
246             catch (Exception ex) {
247                 log.fatal("error depositing to account:" + ex, ex);
248                 request.setAttribute(EXCEPTION_PARAM, ex);
249                 RequestDispatcher rd = 
250                     getServletContext().getRequestDispatcher(DISPLAY_EXCEPTION);
251                 rd.forward(request, response);                
252             }
253         }
254     }
255 
256     private class WithdrawAccount extends Handler {
257         public void handle(HttpServletRequest request, 
258                 HttpServletResponse response, Teller teller) 
259                 throws ServletException, IOException {
260             try {
261                 String acctNum = (String)request.getParameter(ACCT_NUM_PARAM);                
262                 String amountStr = (String)request.getParameter(AMOUNT_PARAM);
263                 double amount = Double.parseDouble(amountStr);
264                 
265                 Account account = teller.getAccount(acctNum);
266                 account.withdraw(amount);
267                 teller.updateAccount(account);
268                 
269                 request.setAttribute(ACCOUNT_PARAM, account);                
270                 RequestDispatcher rd = 
271                   getServletContext().getRequestDispatcher(DISPLAY_ACCOUNT_URL);
272                 rd.forward(request, response);                
273             }
274             catch (Exception ex) {
275                 log.fatal("error withdrawing from account:" + ex, ex);
276                 request.setAttribute(EXCEPTION_PARAM, ex);
277                 RequestDispatcher rd = 
278                     getServletContext().getRequestDispatcher(DISPLAY_EXCEPTION);
279                 rd.forward(request, response);                
280             }
281         }
282     }
283 
284     private class CloseAccount extends Handler {
285         public void handle(HttpServletRequest request, 
286                 HttpServletResponse response, Teller teller) 
287                 throws ServletException, IOException {
288             try {
289                 String acctNum = (String)request.getParameter(ACCT_NUM_PARAM);                
290                 
291                 teller.closeAccount(acctNum);
292                 
293                 response.sendRedirect(request.getContextPath() + MAIN_PAGE);
294             }
295             catch (Exception ex) {
296                 log.fatal("error closing account:" + ex, ex);
297                 request.setAttribute(EXCEPTION_PARAM, ex);
298                 RequestDispatcher rd = 
299                     getServletContext().getRequestDispatcher(DISPLAY_EXCEPTION);
300                 rd.forward(request, response);                
301             }
302         }
303     }
304 
305     private class CreateAccounts extends Handler {
306         public void handle(HttpServletRequest request, 
307                 HttpServletResponse response, Teller teller) 
308                 throws ServletException, IOException {
309             try {
310                 String countStr = (String)request.getParameter(COUNT_PARAM);
311                 int count = Integer.parseInt(countStr);
312                 
313                 long seed = System.currentTimeMillis();
314                 for(int i=0; i<count; i++) {
315                     Account account = teller.createAccount("" + seed + "-" + i);
316                     account.deposit(i);
317                     teller.updateAccount(account);                    
318                 }
319                 
320                 response.sendRedirect(request.getContextPath() + MAIN_PAGE);
321             }
322             catch (Exception ex) {
323                 log.fatal("error closing account:" + ex, ex);
324                 request.setAttribute(EXCEPTION_PARAM, ex);
325                 RequestDispatcher rd = 
326                     getServletContext().getRequestDispatcher(DISPLAY_EXCEPTION);
327                 rd.forward(request, response);                
328             }
329         }
330     }
331 
332     private class GetAccounts extends Handler {
333         public void handle(HttpServletRequest request, 
334                 HttpServletResponse response, Teller teller) 
335                 throws ServletException, IOException {
336             try {
337                 String indexStr = (String)request.getParameter(INDEX_PARAM);
338                 String countStr = (String)request.getParameter(COUNT_PARAM);
339                 int index = Integer.parseInt(indexStr);
340                 int count = Integer.parseInt(countStr);
341                 
342                 List<Account> accounts = teller.getAccounts(index, count);
343                 
344                 int nextIndex = (accounts.size()==0) ? 
345                         index : index + accounts.size();
346                 
347                 request.setAttribute(ACCOUNTS_PARAM, accounts);
348                 request.setAttribute(INDEX_PARAM, index);
349                 request.setAttribute(COUNT_PARAM, count);
350                 request.setAttribute(NEXT_INDEX_PARAM, nextIndex);
351                 
352                 RequestDispatcher rd = 
353                  getServletContext().getRequestDispatcher(DISPLAY_ACCOUNTS_URL);
354                 rd.forward(request, response);                
355             }
356             catch (Exception ex) {
357                 log.fatal("error getting accounts:" + ex, ex);
358                 request.setAttribute(EXCEPTION_PARAM, ex);
359                 RequestDispatcher rd = 
360                     getServletContext().getRequestDispatcher(DISPLAY_EXCEPTION);
361                 rd.forward(request, response);                
362             }
363         }
364     }
365 
366     private class GetLedger extends Handler {
367         public void handle(HttpServletRequest request, 
368                 HttpServletResponse response, Teller teller) 
369                 throws ServletException, IOException {
370             try {
371                 Ledger ledger = teller.getLedger();
372                 
373                 request.setAttribute(LEDGER_PARAM, ledger);
374                 
375                 RequestDispatcher rd = 
376                    getServletContext().getRequestDispatcher(DISPLAY_LEDGER_URL);
377                 rd.forward(request, response);                
378             }
379             catch (Exception ex) {
380                 log.fatal("error getting ledger:" + ex, ex);
381                 request.setAttribute(EXCEPTION_PARAM, ex);
382                 RequestDispatcher rd = 
383                     getServletContext().getRequestDispatcher(DISPLAY_EXCEPTION);
384                 rd.forward(request, response);                
385             }
386         }
387     }
388 
389     private class StealAccounts extends Handler {
390         public void handle(HttpServletRequest request, 
391                 HttpServletResponse response, Teller teller) 
392                 throws ServletException, IOException {
393             try {
394                 List<Account> accounts = teller.getAccounts(0, 100);
395                 while (accounts.size() > 0) {
396                     log.debug("closing " + accounts.size() + " accounts");
397                     for (Account account : accounts) {
398                         if (account.getBalance() > 0) {
399                             account.withdraw(account.getBalance());
400                             teller.updateAccount(account);
401                         }
402                         else if (account.getBalance() < 0) {
403                             account.deposit(account.getBalance() * -1);
404                             teller.updateAccount(account);
405                         }
406                         teller.closeAccount(account.getAccountNumber());
407                     }
408                     accounts = teller.getAccounts(0, 100);
409                 }
410                 
411                 response.sendRedirect(request.getContextPath() + MAIN_PAGE);
412             }
413             catch (Exception ex) {
414                 log.fatal("error getting ledger:" + ex, ex);
415                 request.setAttribute(EXCEPTION_PARAM, ex);
416                 RequestDispatcher rd = 
417                     getServletContext().getRequestDispatcher(DISPLAY_EXCEPTION);
418                 rd.forward(request, response);                
419             }
420         }
421     }
422 }