View Javadoc

1   package org.appfuse.webapp.controller;
2   
3   import org.apache.commons.logging.Log;
4   import org.apache.commons.logging.LogFactory;
5   import org.appfuse.Constants;
6   import org.appfuse.model.User;
7   import org.appfuse.service.MailEngine;
8   import org.appfuse.service.UserManager;
9   import org.springframework.beans.factory.annotation.Autowired;
10  import org.springframework.beans.propertyeditors.CustomDateEditor;
11  import org.springframework.beans.propertyeditors.CustomNumberEditor;
12  import org.springframework.context.MessageSource;
13  import org.springframework.context.support.MessageSourceAccessor;
14  import org.springframework.mail.SimpleMailMessage;
15  import org.springframework.validation.Validator;
16  import org.springframework.web.bind.ServletRequestDataBinder;
17  import org.springframework.web.bind.annotation.InitBinder;
18  import org.springframework.web.context.ServletContextAware;
19  import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;
20  
21  import javax.servlet.ServletContext;
22  import javax.servlet.http.HttpServletRequest;
23  import java.io.Serializable;
24  import java.text.SimpleDateFormat;
25  import java.util.ArrayList;
26  import java.util.Date;
27  import java.util.HashMap;
28  import java.util.List;
29  import java.util.Locale;
30  import java.util.Map;
31  
32  /**
33   * Implementation of <strong>SimpleFormController</strong> that contains
34   * convenience methods for subclasses.  For example, getting the current
35   * user and saving messages/errors. This class is intended to
36   * be a base class for all Form controllers.
37   *
38   * <p><a href="BaseFormController.java.html"><i>View Source</i></a></p>
39   *
40   * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
41   */
42  public class BaseFormController implements ServletContextAware {
43      public static final String MESSAGES_KEY = "successMessages";
44      public static final String ERRORS_MESSAGES_KEY = "errors";
45      protected final transient Log log = LogFactory.getLog(getClass());
46      private UserManager userManager = null;
47      protected MailEngine mailEngine = null;
48      protected SimpleMailMessage message = null;
49      protected String templateName = "accountCreated.vm";
50      protected String cancelView;
51      protected String successView;
52  
53      private MessageSourceAccessor messages;
54      private ServletContext servletContext;
55  
56      @Autowired(required = false)
57      Validator validator;
58  
59      @Autowired
60      public void setMessages(MessageSource messageSource) {
61          messages = new MessageSourceAccessor(messageSource);
62      }
63  
64      @Autowired
65      public void setUserManager(UserManager userManager) {
66          this.userManager = userManager;
67      }
68  
69      public UserManager getUserManager() {
70          return this.userManager;
71      }
72  
73      @SuppressWarnings("unchecked")
74      public void saveError(HttpServletRequest request, String error) {
75          List errors = (List) request.getSession().getAttribute(ERRORS_MESSAGES_KEY);
76          if (errors == null) {
77              errors = new ArrayList();
78          }
79          errors.add(error);
80          request.getSession().setAttribute(ERRORS_MESSAGES_KEY, errors);
81      }
82      
83      @SuppressWarnings("unchecked")
84      public void saveMessage(HttpServletRequest request, String msg) {
85          List messages = (List) request.getSession().getAttribute(MESSAGES_KEY);
86  
87          if (messages == null) {
88              messages = new ArrayList();
89          }
90  
91          messages.add(msg);
92          request.getSession().setAttribute(MESSAGES_KEY, messages);
93      }
94  
95      /**
96       * Convenience method for getting a i18n key's value.  Calling
97       * getMessageSourceAccessor() is used because the RequestContext variable
98       * is not set in unit tests b/c there's no DispatchServlet Request.
99       *
100      * @param msgKey
101      * @param locale the current locale
102      * @return
103      */
104     public String getText(String msgKey, Locale locale) {
105         return messages.getMessage(msgKey, locale);
106     }
107 
108     /**
109      * Convenient method for getting a i18n key's value with a single
110      * string argument.
111      *
112      * @param msgKey
113      * @param arg
114      * @param locale the current locale
115      * @return
116      */
117     public String getText(String msgKey, String arg, Locale locale) {
118         return getText(msgKey, new Object[] { arg }, locale);
119     }
120 
121     /**
122      * Convenience method for getting a i18n key's value with arguments.
123      *
124      * @param msgKey
125      * @param args
126      * @param locale the current locale
127      * @return
128      */
129     public String getText(String msgKey, Object[] args, Locale locale) {
130         return messages.getMessage(msgKey, args, locale);
131     }
132 
133     /**
134      * Convenience method to get the Configuration HashMap
135      * from the servlet context.
136      *
137      * @return the user's populated form from the session
138      */
139     public Map getConfiguration() {
140         Map config = (HashMap) servletContext.getAttribute(Constants.CONFIG);
141 
142         // so unit tests don't puke when nothing's been set
143         if (config == null) {
144             return new HashMap();
145         }
146 
147         return config;
148     }
149 
150     /**
151      * Set up a custom property editor for converting form inputs to real objects
152      * @param request the current request
153      * @param binder the data binder
154      */
155     @InitBinder
156     protected void initBinder(HttpServletRequest request,
157                               ServletRequestDataBinder binder) {
158         binder.registerCustomEditor(Integer.class, null,
159                                     new CustomNumberEditor(Integer.class, null, true));
160         binder.registerCustomEditor(Long.class, null,
161                                     new CustomNumberEditor(Long.class, null, true));
162         binder.registerCustomEditor(byte[].class,
163                                     new ByteArrayMultipartFileEditor());
164         SimpleDateFormat dateFormat = 
165             new SimpleDateFormat(getText("date.format", request.getLocale()));
166         dateFormat.setLenient(false);
167         binder.registerCustomEditor(Date.class, null, 
168                                     new CustomDateEditor(dateFormat, true));
169     }
170 
171     /**
172      * Convenience message to send messages to users, includes app URL as footer.
173      * @param user the user to send a message to.
174      * @param msg the message to send.
175      * @param url the URL of the application.
176      */
177     protected void sendUserMessage(User user, String msg, String url) {
178         if (log.isDebugEnabled()) {
179             log.debug("sending e-mail to user [" + user.getEmail() + "]...");
180         }
181 
182         message.setTo(user.getFullName() + "<" + user.getEmail() + ">");
183 
184         Map<String, Serializable> model = new HashMap<String, Serializable>();
185         model.put("user", user);
186 
187         // TODO: once you figure out how to get the global resource bundle in
188         // WebWork, then figure it out here too.  In the meantime, the Username
189         // and Password labels are hard-coded into the template. 
190         // model.put("bundle", getTexts());
191         model.put("message", msg);
192         model.put("applicationURL", url);
193         mailEngine.sendMessage(message, templateName, model);
194     }
195 
196     @Autowired
197     public void setMailEngine(MailEngine mailEngine) {
198         this.mailEngine = mailEngine;
199     }
200 
201     @Autowired
202     public void setMessage(SimpleMailMessage message) {
203         this.message = message;
204     }
205 
206     public void setTemplateName(String templateName) {
207         this.templateName = templateName;
208     }
209    
210     public final BaseFormController setCancelView(String cancelView) {
211         this.cancelView = cancelView;
212         return this;
213     }
214 
215     public final String getCancelView() {
216         // Default to successView if cancelView is invalid
217         if (this.cancelView == null || this.cancelView.length()==0) {
218             return getSuccessView();
219         }
220         return this.cancelView;   
221     }
222 
223     public final String getSuccessView() {
224         return this.successView;
225     }
226     
227     public final BaseFormController setSuccessView(String successView) {
228         this.successView = successView;
229         return this;
230     }
231 
232     public void setServletContext(ServletContext servletContext) {
233         this.servletContext = servletContext;
234     }
235 
236     protected ServletContext getServletContext() {
237         return servletContext;
238     }
239 }