View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.struts.apps.mailreader.actions;
18  
19  import java.lang.reflect.InvocationTargetException;
20  
21  import jakarta.servlet.ServletException;
22  import jakarta.servlet.http.HttpServletRequest;
23  import jakarta.servlet.http.HttpServletResponse;
24  import jakarta.servlet.http.HttpSession;
25  
26  import org.apache.commons.beanutils.PropertyUtils;
27  import org.apache.struts.action.ActionForm;
28  import org.apache.struts.action.ActionForward;
29  import org.apache.struts.action.ActionMapping;
30  import org.apache.struts.apps.mailreader.Constants;
31  import org.apache.struts.apps.mailreader.dao.Subscription;
32  import org.apache.struts.apps.mailreader.dao.User;
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  
36  /**
37   * <p>
38   * Provide an Edit method for retrieving an existing subscription,
39   * and a Save method for updating or inserting a subscription.
40   * </p>
41   */
42  public final class SubscriptionAction extends BaseAction {
43      private static final long serialVersionUID = 481958664313412332L;
44  
45      /**
46       * The {@code Log} instance for this class.
47       */
48      private final static Logger LOG =
49          LoggerFactory.getLogger(SubscriptionAction.class);
50  
51      // --- Public Constants --
52  
53      /**
54       * <p>
55       * Name of autoConnect field ["autoConnect"].
56       * </p>
57       */
58      public final static String AUTO_CONNECT = "autoConnect";
59  
60      /**
61       * <p>
62       * Name of host field ["host"].
63       * </p>
64       */
65      public final static String HOST = "host";
66  
67      /**
68       * <p>
69       * Name of type field ["type"].
70       * </p>
71       */
72      public final static String TYPE = "type";
73  
74      // ---- Private Methods ----
75  
76      final String LOG_SUBSCRIPTION_POPULATE = "SubscriptionForm.populate";
77  
78      /**
79       * <p>
80       * Obtain subscription matching host for the given User,
81       * or return null if not found.
82       * </p>
83       *
84       * @param user Our User object
85       * @param host The name of the mail server host
86       * @return The matching Subscription or null
87       */
88      private Subscription doFindSubscription(User user, String host) {
89  
90          Subscription subscription;
91  
92          try {
93              subscription = user.findSubscription(host);
94          }
95          catch (NullPointerException e) {
96              subscription = null;
97          }
98  
99          if (subscription == null) {
100             LOG.trace(" No subscription for user {} and host {}",
101                 user.getUsername(), host);
102         }
103 
104         return subscription;
105     }
106 
107     /**
108      * <p>
109      * Helper method to populate the Subscription object from the input form.
110      * </p>
111      *
112      * @param subscription User object to populate
113      * @param form         Form with incoming values
114      * @throws ServletException On any error
115      */
116     private void doPopulate(Subscription subscription, ActionForm form)
117             throws ServletException {
118 
119         LOG.trace("{}{}", Constants.LOG_POPULATE_SUBSCRIPTION, subscription);
120 
121         try {
122             PropertyUtils.copyProperties(subscription, form);
123         } catch (InvocationTargetException e) {
124             Throwable t = e.getTargetException();
125             if (t == null) {
126                 t = e;
127             }
128             LOG.error(LOG_SUBSCRIPTION_POPULATE, t);
129             throw new ServletException(LOG_SUBSCRIPTION_POPULATE, t);
130         } catch (Throwable t) {
131             LOG.error(LOG_SUBSCRIPTION_POPULATE, t);
132             throw new ServletException(LOG_SUBSCRIPTION_POPULATE, t);
133         }
134     }
135 
136     /**
137      * <p>
138      * Helper method to populate the input form from the Subscription object.
139      * </p>
140      *
141      * @param subscription User object to populate
142      * @param form         Form with incoming values
143      * @throws ServletException On any error
144      */
145     private void doPopulate(ActionForm form, Subscription subscription)
146             throws ServletException {
147 
148         final String title = Constants.EDIT;
149 
150         LOG.trace("{}{}", Constants.LOG_POPULATE_FORM, subscription.getHost());
151 
152         try {
153             PropertyUtils.copyProperties(form, subscription);
154             doSet(form, TASK, title);
155         } catch (InvocationTargetException e) {
156             Throwable t = e.getTargetException();
157             if (t == null) {
158                 t = e;
159             }
160             LOG.error(LOG_SUBSCRIPTION_POPULATE, t);
161             throw new ServletException(LOG_SUBSCRIPTION_POPULATE, t);
162         } catch (Throwable t) {
163             LOG.error(LOG_SUBSCRIPTION_POPULATE, t);
164             throw new ServletException(LOG_SUBSCRIPTION_POPULATE, t);
165         }
166     }
167 
168     /**
169      * <p>
170      * Remove the given subscription for this user.
171      * </p>
172      *
173      * @param mapping      Our ActionMapping
174      * @param session      Our HttpSession
175      * @param user         Our User
176      * @param subscription Subscription to delete
177      * @return "Success" if delete is nominal, "Logon" if attributes are
178      *         missing
179      * @throws ServletException if updates fails
180      */
181     private ActionForward doRemoveSubscription(
182             ActionMapping mapping,
183             HttpSession session,
184             User user,
185             Subscription subscription)
186             throws ServletException {
187 
188         final String method = Constants.DELETE;
189         doLogProcess(mapping, method);
190 
191         LOG.trace(" Deleting subscription to mail server '{}' for user '{}'",
192             subscription.getHost(), user.getUsername());
193 
194         boolean missingAttributes = ((user == null) || (subscription == null));
195         if (missingAttributes) {
196             return doFindLogon(mapping);
197         }
198 
199         user.removeSubscription(subscription);
200         session.removeAttribute(Constants.SUBSCRIPTION_KEY);
201         doSaveUser(user);
202 
203         return doFindSuccess(mapping);
204     }
205 
206     // ----- Public Methods ----
207 
208     /**
209      * <p>
210      * Prepare for a Delete operation by populating the form
211      * and seting the action to Delete.
212      * </p>
213      *
214      * @param mapping  Our ActionMapping
215      * @param form     Our ActionForm
216      * @param request  Our HttpServletRequest
217      * @param response Our HttpServletResponse
218      * @return The "Success" result for this mapping
219      * @throws Exception on any error
220      */
221     public ActionForward Delete(
222             ActionMapping mapping,
223             ActionForm form,
224             HttpServletRequest request,
225             HttpServletResponse response)
226             throws Exception {
227 
228         final String method = Constants.DELETE;
229         doLogProcess(mapping, method);
230 
231         ActionForward result = Edit(mapping, form, request, response);
232 
233         doSet(form, TASK, method);
234         return result;
235     }
236 
237     /**
238      * <p>
239      * Retrieve the Subscription object to edit
240      * or null if the Subscription does not exist.
241      * </p><p>
242      * The Subscription object is bound to the User,
243      * and so if the User is not logged in,
244      * control is forwarded to the Logon result.
245      * </p>
246      *
247      * @param mapping  Our ActionMapping
248      * @param form     Our ActionForm
249      * @param request  Our HttpServletRequest
250      * @param response Our HttpServletResponse
251      * @return The "Success" result for this mapping
252      * @throws Exception on any error
253      */
254     public ActionForward Edit(
255             ActionMapping mapping,
256             ActionForm form,
257             HttpServletRequest request,
258             HttpServletResponse response)
259             throws Exception {
260 
261         final String method = Constants.EDIT;
262         doLogProcess(mapping, method);
263 
264         HttpSession session = request.getSession();
265         User user = doGetUser(session);
266         if (user == null) {
267             return doFindLogon(mapping);
268         }
269 
270         // Retrieve the subscription, if there is one
271         Subscription subscription;
272         String host = doGet(form, HOST);
273         boolean updating = (host != null);
274         if (updating) {
275             subscription = doFindSubscription(user, host);
276             if (subscription == null) {
277                 return doFindFailure(mapping);
278             }
279             session.setAttribute(Constants.SUBSCRIPTION_KEY, subscription);
280             doPopulate(form, subscription);
281             doSet(form, TASK, method);
282         }
283 
284         return doFindSuccess(mapping);
285     }
286 
287     /**
288      * <p>
289      * Insert or update a Subscription object to the persistent store.
290      * </p>
291      *
292      * @param mapping  Our ActionMapping
293      * @param form     Our ActionForm
294      * @param request  Our HttpServletRequest
295      * @param response Our HttpServletResponse
296      * @return The "Success" result for this mapping
297      * @throws Exception on any error
298      */
299     public ActionForward Save(
300             ActionMapping mapping,
301             ActionForm form,
302             HttpServletRequest request,
303             HttpServletResponse response)
304             throws Exception {
305 
306         final String method = Constants.SAVE;
307         doLogProcess(mapping, method);
308 
309         User user = doGetUser(request);
310         if (user == null) {
311             return doFindLogon(mapping);
312         }
313 
314         HttpSession session = request.getSession();
315         if (isCancelled(request)) {
316             doCancel(session, method, Constants.SUBSCRIPTION_KEY);
317             return doFindSuccess(mapping);
318         }
319 
320         String action = doGet(form, TASK);
321         Subscription subscription = doGetSubscription(request);
322         boolean isDelete = action.equals(Constants.DELETE);
323         if (isDelete) {
324             return doRemoveSubscription(mapping, session, user, subscription);
325         }
326 
327         if (subscription == null) {
328             subscription = user.createSubscription(doGet(form, HOST));
329             session.setAttribute(Constants.SUBSCRIPTION_KEY, subscription);
330         }
331 
332         doPopulate(subscription, form);
333         doSaveUser(user);
334         session.removeAttribute(Constants.SUBSCRIPTION_KEY);
335 
336         return doFindSuccess(mapping);
337     }
338 }