View Javadoc

1   /**
2    * - Digitalis Internal Framework v2.0 - (C) 2007, Digitalis Informatica. Distribuicao e Gestao de Informatica, Lda.
3    * Estrada de Paco de Arcos num.9 - Piso -1 2780-666 Paco de Arcos Telefone: (351) 21 4408990 Fax: (351) 21 4408999
4    * http://www.digitalis.pt
5    */
6   package pt.digitalis.dif.controller.objects;
7   
8   import java.util.HashMap;
9   import java.util.Map;
10  
11  import pt.digitalis.dif.controller.http.HTTPConstants;
12  import pt.digitalis.dif.controller.interfaces.IDIFContext;
13  import pt.digitalis.dif.controller.interfaces.IDIFRequest;
14  import pt.digitalis.dif.controller.interfaces.IDIFSession;
15  import pt.digitalis.dif.dem.interfaces.IStage;
16  import pt.digitalis.dif.dem.managers.IDEMManager;
17  import pt.digitalis.dif.dem.managers.impl.UsageIssuesManagerImpl;
18  import pt.digitalis.dif.dem.objects.EventType;
19  import pt.digitalis.dif.dem.objects.ViewObject;
20  import pt.digitalis.dif.dem.objects.issues.IssueScope;
21  import pt.digitalis.dif.dem.objects.issues.IssueType;
22  import pt.digitalis.dif.dem.objects.issues.UsageIssue;
23  import pt.digitalis.dif.ioc.DIFIoCRegistry;
24  import pt.digitalis.dif.startup.DIFGeneralConfigurationParameters;
25  import pt.digitalis.dif.utils.ObjectFormatter;
26  import pt.digitalis.dif.utils.logging.DIFLogger;
27  import pt.digitalis.utils.common.CollectionUtils;
28  import pt.digitalis.utils.common.SystemUtils;
29  
30  /**
31   * This class is the base class for the DIF execution context.
32   * 
33   * @author Rodrigo Gonçalves <a href="mailto:rgoncalves@digitalis.pt">rgoncalves@digitalis.pt</a>
34   * @created 2007/03/16
35   */
36  public class DIFContext implements IDIFContext {
37  
38      /** The DIFRequest. */
39      private IDIFRequest difRequest = null;
40  
41      /**
42       * Marks the defined stage for redirection processing by the Dispatcher
43       */
44      private boolean hasRedirection = false;
45  
46      /** the result message */
47      private ResultMessage resultMessage = null;
48  
49      /**
50       * Identifier of the Stage that should be executed.
51       */
52      private String stage = new String();
53  
54      /** The processing result set. */
55      private Map<String, Object> stageResults = new HashMap<String, Object>();
56  
57      /**
58       * Identifier of the Stage to redirect after execution of the current Stage.
59       */
60      private String stageToRedirect = new String();
61  
62      /** A map of custom attributes for stage usage. These will have the same life span of this DIFContext instance */
63      private Map<String, Object> temporaryAttributes = new HashMap<String, Object>();
64  
65      /**
66       * The ViewObject.
67       */
68      protected ViewObject theView = new ViewObject();
69  
70      /**
71       * @see pt.digitalis.dif.controller.interfaces.IDIFContext#addResultMessage(java.lang.String, java.lang.String,
72       *      java.lang.String)
73       */
74      public void addResultMessage(String type, String title, String description)
75      {
76          addResultMessage(type, title, description, null);
77      }
78  
79      /**
80       * @see pt.digitalis.dif.controller.interfaces.IDIFContext#addResultMessage(java.lang.String, java.lang.String,
81       *      java.lang.String, boolean)
82       */
83      public void addResultMessage(String type, String title, String description, boolean popupMode)
84      {
85          resultMessage = new ResultMessage(type, title, description, popupMode, null);
86      }
87  
88      /**
89       * @see pt.digitalis.dif.controller.interfaces.IDIFContext#addResultMessage(java.lang.String, java.lang.String,
90       *      java.lang.String, java.lang.String)
91       */
92      public void addResultMessage(String type, String title, String description, String mode)
93      {
94          resultMessage = new ResultMessage(type, title, description, false, mode);
95      }
96  
97      /**
98       * @see pt.digitalis.dif.controller.interfaces.IDIFContext#addStageResult(String, Object)
99       */
100     public void addStageResult(String resultName, Object resultValue)
101     {
102         this.stageResults.put(resultName, resultValue);
103     }
104 
105     /**
106      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#getLanguage()
107      */
108     public String getLanguage()
109     {
110         IDIFSession session = getSession();
111 
112         if (session == null)
113             return DIFGeneralConfigurationParameters.getInstance().getDefaultLanguage();
114         else
115             return session.getLanguage();
116     }
117 
118     /**
119      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#getRequest()
120      */
121     public IDIFRequest getRequest()
122     {
123         return difRequest;
124     }
125 
126     /**
127      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#getResultMessage()
128      */
129     public ResultMessage getResultMessage()
130     {
131         return resultMessage;
132     }
133 
134     /**
135      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#getSession()
136      */
137     public IDIFSession getSession()
138     {
139         if (this.difRequest != null)
140         {
141             return this.difRequest.getSession();
142         }
143         else
144         {
145             return null;
146         }
147     }
148 
149     /**
150      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#getStage()
151      */
152     public String getStage()
153     {
154         return this.stage;
155     }
156 
157     /**
158      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#getStageResults()
159      */
160     public final Map<String, Object> getStageResults()
161     {
162         return stageResults;
163     }
164 
165     /**
166      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#getTemporaryAttributes()
167      */
168     public Map<String, Object> getTemporaryAttributes()
169     {
170         return temporaryAttributes;
171     }
172 
173     /**
174      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#getView()
175      */
176     public ViewObject getView()
177     {
178         return this.theView;
179     }
180 
181     /**
182      * This method sets the current stage equal to the redirection stage. The redirection stage is set to null and a the
183      * redirection flag is set to T. The stage results are reset.
184      * 
185      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#handleRedirection()
186      */
187     public void handleRedirection()
188     {
189         this.stage = this.stageToRedirect;
190         this.stageToRedirect = null;
191         this.hasRedirection = false;
192     }
193 
194     /**
195      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#hasRedirection()
196      */
197     public boolean hasRedirection()
198     {
199         return this.hasRedirection;
200     }
201 
202     /**
203      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#redirectTo(java.lang.String)
204      */
205     public void redirectTo(String newStage)
206     {
207         this.redirectTo(newStage, "");
208     }
209 
210     /**
211      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#redirectTo(java.lang.String, boolean)
212      */
213     public void redirectTo(String newStage, boolean allowRedirectToSameStage)
214     {
215         this.redirectTo(newStage, "", allowRedirectToSameStage);
216     }
217 
218     /**
219      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#redirectTo(java.lang.String, java.util.Map)
220      */
221     public void redirectTo(String newStage, Map<String, Object> redirectionParameters)
222     {
223         this.redirectTo(newStage, redirectionParameters, false);
224     }
225 
226     /**
227      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#redirectTo(java.lang.String, java.util.Map, boolean)
228      */
229     public void redirectTo(String newStage, Map<String, Object> redirectionParameters, boolean allowRedirectToSameStage)
230     {
231 
232         // Prevent redirect to the current stage and thus might allow indefinite cyclic redirects
233         if (allowRedirectToSameStage || !this.getStage().equals(newStage))
234         {
235             this.stageToRedirect = newStage;
236             this.hasRedirection = true;
237 
238             if (redirectionParameters != null && !redirectionParameters.isEmpty())
239             {
240                 this.difRequest.setParameters(redirectionParameters);
241             }
242         }
243         else
244             DIFLogger.getLogger().warn(
245                     "Prevented a redirection to the same stage: \"" + stageToRedirect
246                             + "\" (cyclic redirection danger!).");
247     }
248 
249     /**
250      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#redirectTo(java.lang.String, java.lang.String)
251      */
252     public void redirectTo(String newStage, String redirectionParameters)
253     {
254         redirectTo(newStage, redirectionParameters, false);
255     }
256 
257     /**
258      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#redirectTo(java.lang.String, java.lang.String, boolean)
259      */
260     public void redirectTo(String newStage, String redirectionParameters, boolean allowRedirectToSameStage)
261     {
262         Map<String, Object> parameterMap = new HashMap<String, Object>();
263 
264         if (redirectionParameters != null && !"".equals(redirectionParameters))
265             parameterMap = CollectionUtils.keyValueStringToMapObject(redirectionParameters);
266 
267         redirectTo(newStage, parameterMap, allowRedirectToSameStage);
268     }
269 
270     /**
271      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#reportIssue(java.lang.String,
272      *      pt.digitalis.dif.dem.objects.issues.IssueType, java.lang.String)
273      */
274     public void reportIssue(String uID, IssueType type, String issueDescription)
275     {
276         this.reportIssue(uID, type, issueDescription, null);
277     }
278 
279     /**
280      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#reportIssue(java.lang.String,
281      *      pt.digitalis.dif.dem.objects.issues.IssueType, java.lang.String, java.lang.Exception)
282      */
283     public void reportIssue(String uID, IssueType type, String issueDescription, Exception exception)
284     {
285         this.reportIssue(uID, type, issueDescription, exception, true);
286     }
287 
288     /**
289      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#reportIssue(java.lang.String,
290      *      pt.digitalis.dif.dem.objects.issues.IssueType, java.lang.String, java.lang.Exception, boolean)
291      */
292     public void reportIssue(String uID, IssueType type, String issueDescription, Exception exception,
293             boolean showStackTrace)
294     {
295         IStage stage = DIFIoCRegistry.getRegistry().getImplementation(IDEMManager.class).getStage(this.getStage());
296 
297         Object submitForm = this.getRequest().getParameter(HTTPConstants.FORM_SUBMIT_NAME);
298         Object eventID = this.getRequest().getParameter(HTTPConstants.EVENT_ID);
299         EventType eventType = null;
300 
301         // If form submitted check if an event handler for it exists
302         if (stage.getEventHandlers().get(EventType.FORM_SUBMIT).contains(submitForm))
303             eventType = EventType.FORM_SUBMIT;
304         else if (stage.getEventHandlers().get(EventType.FORM_SUBMIT_SAVE_ACTION).contains(submitForm))
305             eventType = EventType.FORM_SUBMIT_SAVE_ACTION;
306         else if (stage.getEventHandlers().get(EventType.FORM_SUBMIT_AJAX_REQUEST).contains(submitForm))
307             eventType = EventType.FORM_SUBMIT_AJAX_REQUEST;
308         else if (stage.getEventHandlers().get(EventType.AJAX_REQUEST).contains(eventID))
309             eventType = EventType.AJAX_REQUEST;
310         else if (stage.getEventHandlers().get(EventType.DOCUMENT_TYPE).contains(eventID))
311             eventType = EventType.DOCUMENT_TYPE;
312 
313         if (eventID != null)
314             issueDescription += " | <b>Event:</b> " + eventID + (eventType != null ? " [" + eventType + "]" : "");
315         if (submitForm != null)
316             issueDescription += " | <b>Form:</b> " + submitForm;
317 
318         if (showStackTrace)
319         {
320             String traceContent = null;
321 
322             if (showStackTrace)
323             {
324                 if (exception == null)
325                 {
326                     StackTraceElement[] traceList = Thread.currentThread().getStackTrace();
327                     StackTraceElement[] parsedTraceList = new StackTraceElement[traceList.length - 1];
328                     int totalToRemove = 1;
329 
330                     // remove the current call from the original stack
331                     while (traceList[totalToRemove].getMethodName().contains("reportIssue"))
332                         totalToRemove++;
333                     System.arraycopy(traceList, totalToRemove, parsedTraceList, 0, parsedTraceList.length
334                             - totalToRemove);
335 
336                     traceContent = SystemUtils.getStackTraceListHTML(parsedTraceList).toString();
337                 }
338                 else
339                     traceContent = SystemUtils.getStackTraceHTML(exception);
340             }
341 
342             String requestSum = "<b>Stage:</b> " + stage.getOriginalClassName() + "<br/>";
343             if (eventID != null)
344                 requestSum += "<b>Event:</b> " + eventID + (eventType != null ? " [" + eventType + "]" : "") + "<br/>";
345             if (submitForm != null)
346                 requestSum += "<b>Form:</b> " + submitForm + "<br/>";
347 
348             StringBuffer buffer = new StringBuffer();
349             buffer.append("Ext.create('Ext.window.Window',{");
350             buffer.append("title: 'Track of the orginating execution of the issue',");
351             buffer.append("width:800,height:460,laytout:'border',modal:true,");
352             buffer.append("buttonAlign:'center',buttons:[{ text: 'OK',handler:function(b){b.up('window').close()}}],");
353             buffer.append("defaults:{autoScroll:true,bodyPadding:5},");
354             buffer.append("items:[{");
355             buffer.append("region:'north',height:150,bodyCls:'backgthememedium',html: '" + requestSum + "<br/>"
356                     + issueDescription + "'");
357             buffer.append("},{xtype:'tabpanel',height:270,region:'center',laytout:'fit',defaults:{autoScroll:true,bodyPadding:5},items:[{");
358             buffer.append("title:'Stack Trace',html: '"
359                     + (traceContent == null ? "No stack trace available!" : traceContent.replaceAll("\n", "")
360                             .replaceAll("\\\'", "\\\\\'").replaceAll("\\\"", "\\\\\\\\\'")) + "'");
361             buffer.append("},{title:'Context',html: '<code>"
362                     + this.toString().replaceAll("\n", "<br/>").replaceAll("\\\'", "\\\\\'")
363                             .replaceAll("\\\"", "\\\\\\\\\'") + "</code>'");
364             buffer.append("}]}]}).show();");
365 
366             issueDescription = issueDescription.split("<br/>")[0].split("<br />")[0].split("<br>")[0].split("\n")[0]
367                     + "<a onClick=\"" + buffer.toString() + "\"> | More details</a>";
368         }
369 
370         UsageIssue issue = new UsageIssue();
371         issue.setUID(uID == null ? null : this.getStage() + uID);
372         issue.setIssueScope(IssueScope.RUNTIME);
373         issue.setIssueType(type);
374         issue.setIssueDescription(issueDescription);
375         issue.setLocation(stage.getOriginalClassName());
376         issue.setException(exception);
377         issue.setContext(this);
378 
379         this.reportIssue(issue);
380     }
381 
382     /**
383      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#reportIssue(pt.digitalis.dif.dem.objects.issues.UsageIssue)
384      */
385     public void reportIssue(UsageIssue issue)
386     {
387         UsageIssuesManagerImpl.getInstance().addIssue(issue);
388     }
389 
390     /**
391      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#setRequest(pt.digitalis.dif.controller.interfaces.IDIFRequest)
392      */
393     public void setRequest(IDIFRequest difRequest)
394     {
395         this.difRequest = difRequest;
396     }
397 
398     /**
399      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#setSession(IDIFSession)
400      */
401     public void setSession(IDIFSession session)
402     {
403         this.difRequest.setSession(session);
404     }
405 
406     /**
407      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#setStage(String)
408      */
409     public void setStage(String stage)
410     {
411         this.stage = stage;
412     }
413 
414     /**
415      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#setStageResults(Map)
416      */
417     public final void setStageResults(Map<String, Object> results)
418     {
419         this.stageResults = results;
420     }
421 
422     /**
423      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#setTemporaryAttributes(java.util.Map)
424      */
425     public void setTemporaryAttributes(Map<String, Object> temporaryAttributes)
426     {
427         this.temporaryAttributes = temporaryAttributes;
428     }
429 
430     /**
431      * @see pt.digitalis.dif.controller.interfaces.IDIFContext#setView(ViewObject)
432      */
433     public void setView(ViewObject newView)
434     {
435         this.theView = newView;
436     }
437 
438     /**
439      * Prints the context information on an human-readable form. Overrides java.lang.Object#toString().
440      * 
441      * @see java.lang.Object#toString()
442      */
443     @Override
444     public String toString()
445     {
446         ObjectFormatter formatter = new ObjectFormatter();
447         formatter.addItem("Request", difRequest);
448         formatter.addItem("Has Redirection", hasRedirection);
449         formatter.addItem("View", theView);
450         formatter.addItem("Stage", stage);
451         formatter.addItem("Stage Results", stageResults);
452         formatter.addItemIfNotNull("Stage to redirect", stageToRedirect);
453 
454         return formatter.getFormatedObject();
455     }
456 }