View Javadoc

1   /*
2    * $Id: ControllerServlet.java 126 2004-11-01 20:30:33Z josem $
3    *
4    * Tarsis
5    * Copyright (C) 2002 Talika Open Source Group
6    *
7    * This program is free software; you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, write to the Free Software
19   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20   *
21   */
22  
23  package org.talika.tarsis.servlets;
24  
25  import java.io.IOException;
26  
27  import javax.servlet.ServletConfig;
28  import javax.servlet.ServletException;
29  import javax.servlet.http.HttpServletRequest;
30  import javax.servlet.http.HttpServletResponse;
31  
32  import org.talika.tarsis.command.Command;
33  import org.talika.tarsis.command.Request;
34  import org.talika.tarsis.command.RequestImpl;
35  import org.talika.tarsis.command.Response;
36  import org.talika.tarsis.command.ResponseImpl;
37  import org.talika.tarsis.command.action.Action;
38  import org.talika.tarsis.command.action.ActionException;
39  import org.talika.tarsis.command.factory.CommandFactory;
40  import org.talika.tarsis.command.view.View;
41  import org.talika.tarsis.error.SystemException;
42  import org.talika.tarsis.util.CommandHelper;
43  
44  /**
45   * Implementation of controller servlet of Tarsis MVC Framework.<br>
46   * <br>
47   *
48   * @author  Jose M. Palomar
49   * @version $Revision: 126 $
50   */
51  public final class ControllerServlet extends AbstractServlet {
52  
53      // Fields
54      /**
55       * Command factory instance.
56       */
57      private CommandFactory commandFactory;
58  
59      /**
60       * Command helper instance.
61       */
62      private CommandHelper commandHelper;
63  
64      /**
65       * Called by the servlet container to indicate to a servlet that the servlet is
66       * being placed into service.<br>
67       * <br>
68       * Initialization consits in calling super <code>init</code> method and storing
69       * in a local variable command factory instance for further use.
70       *
71       * @param config ServletConfig the <code>ServletConfig</code> object that contains
72       * configutation information for this servlet.
73       * @throws ServletException if an exception occurs that interrupts the servlet's
74       * normal operation.
75       * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
76       */
77      public void init(ServletConfig config) throws ServletException {
78          super.init(config);
79  
80          this.commandFactory = getContext().getCommandFactory();
81          this.commandHelper = CommandHelper.getInstance();
82  
83      }
84  
85      /**
86       * Called by the servlet container to indicate to a servlet that the servlet is
87       * being taken out of service.
88       *
89       * @see javax.servlet.Servlet#destroy()
90       */
91      public void destroy() {
92  
93          this.commandFactory = null;
94          this.commandHelper = null;
95  
96          super.destroy();
97  
98      }
99  
100     /**
101      * Processes requests for both HTTP GET and POST methods.<br>
102      * <br>
103      * Controller process requests this way:
104      * <ol>
105      * <li>Obtains command from request.</li>
106      * <li>Process command action by calling <code>execute</code> method.</li>
107      * <li>Process command view by forwarding or redirecting to it.</li>
108      * </ol>
109      *
110      * @param request servlet object that contains the request the client has made of
111      * the servlet.
112      * @param response servlet object that contains the response the servlet sends to
113      * the client.
114      * @throws ServletException if the request could not be handled.
115      * @throws IOException if an input or output error is detected when the servlet
116      * handles request.
117      */
118     protected void process(HttpServletRequest request, HttpServletResponse response)
119     throws ServletException, IOException {
120 
121         try {
122 
123             Command command = findCommand(request, response);
124             View view       = processCommand(request, response, command);
125                               processView(request, response, view);
126 
127         }
128         catch (ServletException se) {
129             throw se;
130         }
131         catch (Throwable t) {
132             throw new ServletException(t);
133         }
134 
135     }
136 
137     /**
138      * Obtains command from client's request.
139      *
140      * @param request HttpServletRequest client's request.
141      * @param response HttpServletResponse client's response.
142      * @return Command command obtained from client's request.
143      * @throws SystemException if no command is found.
144      *
145      * @todo Think in some kind of default command feature when no command is found.
146      */
147     protected Command findCommand(HttpServletRequest request, HttpServletResponse response)
148     throws SystemException {
149 
150         // Find command
151         String commandName = commandHelper.getCommand(request);
152         Command command = commandFactory.findCommand(commandName);
153         if (command == null) {
154             throw new SystemException("Unknown command " + commandName);
155         }
156 
157         return command;
158 
159     }
160 
161     /**
162      * Process given command.
163      *
164      * @param request HttpServletRequest client's request.
165      * @param response HttpServletResponse client's reponse.
166      * @param command Command command to be processed.
167      * @return View view result of processing command.
168      * @throws ActionException if there is a problem executing action.
169      * @throws SystemException if no view is found.
170      */
171     protected View processCommand(HttpServletRequest request, HttpServletResponse response,
172     Command command)
173     throws ActionException, SystemException {
174 
175         // Action
176         Action action = command.getAction();
177 
178         // Create helper objects
179         Request req = new RequestImpl(request);
180         Response res = new ResponseImpl(request, response);
181 
182         // Execute action
183         String viewName = action.execute(req, res);
184 
185         // Get view
186         if (viewName == null) {
187             viewName = View.DEFAULT_VIEW_NAME;
188         }
189 
190         View view = command.getView(viewName);
191         if (view == null) {
192             throw new SystemException("Unkown view " + viewName + " in command " + command.getName());
193         }
194 
195         return view;
196 
197     }
198 
199     /**
200      * Process given view.
201      *
202      * @param request HttpServletRequest client's request.
203      * @param response HttpServletResponse client's reponse.
204      * @param view View view to be processed.
205      * @throws SystemException if view's type is unkown.
206      * @throws ServletException if the request could not be handled.
207      * @throws IOException if an input or output error is detected when the servlet
208      * handles request.
209      */
210     protected void processView(HttpServletRequest request, HttpServletResponse response,
211     View view)
212     throws SystemException, ServletException, IOException {
213 
214         switch(view.getType()) {
215             case View.FORWARD:
216                 request.getRequestDispatcher(view.getPath()).forward(request, response);
217                 break;
218             case View.INCLUDE:
219                 request.getRequestDispatcher(view.getPath()).include(request, response);
220                 break;
221             case View.REDIRECT:
222                 response.sendRedirect(view.getPath());
223                 break;
224             default:
225                 throw new SystemException("Unkown view type " + view.getType() +
226                                          " in view " + view.getName());
227         }
228 
229     }
230 
231 }