View Javadoc

1   package org.andromda.cartridges.bpm4struts.metafacades;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.Collections;
6   import java.util.Iterator;
7   import java.util.LinkedHashMap;
8   import java.util.LinkedHashSet;
9   import java.util.List;
10  import java.util.Map;
11  import java.util.TreeMap;
12  
13  import javax.swing.tree.DefaultMutableTreeNode;
14  import javax.swing.tree.TreeNode;
15  
16  import org.andromda.cartridges.bpm4struts.Bpm4StrutsGlobals;
17  import org.andromda.cartridges.bpm4struts.Bpm4StrutsProfile;
18  import org.andromda.cartridges.bpm4struts.Bpm4StrutsUtils;
19  import org.andromda.metafacades.uml.ActivityGraphFacade;
20  import org.andromda.metafacades.uml.FrontEndActivityGraph;
21  import org.andromda.metafacades.uml.Role;
22  import org.andromda.utils.StringUtilsHelper;
23  import org.apache.commons.lang.StringUtils;
24  
25  
26  /**
27   * MetafacadeLogic implementation.
28   *
29   * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsUseCase
30   */
31  public class StrutsUseCaseLogicImpl
32      extends StrutsUseCaseLogic
33  {
34      public StrutsUseCaseLogicImpl(
35          java.lang.Object metaObject,
36          java.lang.String context)
37      {
38          super(metaObject, context);
39      }
40  
41      protected String handleGetTitleKey()
42      {
43          return StringUtilsHelper.toResourceMessageKey(normalizeMessages() ? getTitleValue() : getName()) + ".title";
44      }
45  
46      protected String handleGetTitleValue()
47      {
48          return StringUtilsHelper.toPhrase(getName());
49      }
50  
51      protected String handleGetOnlineHelpKey()
52      {
53          return StringUtilsHelper.toResourceMessageKey(getName()) + ".online.help";
54      }
55  
56      protected String handleGetOnlineHelpValue()
57      {
58          final String crlf = "<br/>";
59          final StringBuffer buffer = new StringBuffer();
60  
61          final String value = StringUtilsHelper.toResourceMessage(getDocumentation("", 64, false));
62          buffer.append((value == null) ? "No use-case documentation has been specified" : value);
63          buffer.append(crlf);
64  
65          return StringUtilsHelper.toResourceMessage(buffer.toString());
66      }
67  
68      protected String handleGetActionPath()
69      {
70          String actionPath = null;
71  
72          final StrutsActivityGraph graph = (StrutsActivityGraph)getActivityGraph();
73          if (graph != null)
74          {
75              final StrutsAction action = graph.getFirstAction();
76              if (action != null)
77              {
78                  actionPath = action.getActionPath();
79              }
80          }
81          return actionPath;
82      }
83  
84      protected String handleGetActionPathRoot()
85      {
86          String actionPathRoot = null;
87  
88          final StrutsActivityGraph graph = (StrutsActivityGraph)getActivityGraph();
89          if (graph != null)
90          {
91              final StrutsAction action = graph.getFirstAction();
92              if (action != null)
93              {
94                  actionPathRoot = action.getActionPathRoot();
95              }
96          }
97          return actionPathRoot;
98      }
99  
100     /**
101      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsUseCase#isCyclic()
102      */
103     protected boolean handleIsCyclic()
104     {
105         boolean selfTargetting = false;
106         final ActivityGraphFacade graph = getActivityGraph();
107         if (graph != null)
108         {
109             final Collection finalStates = graph.getFinalStates();
110             for (final Iterator finalStateIterator = finalStates.iterator();
111                  finalStateIterator.hasNext() && !selfTargetting;)
112             {
113                 final StrutsFinalState finalState = (StrutsFinalState)finalStateIterator.next();
114                 if (this.equals(finalState.getTargetUseCase()))
115                 {
116                     selfTargetting = true;
117                 }
118             }
119         }
120         return selfTargetting;
121     }
122 
123     protected String handleGetActionRoles()
124     {
125         final Collection users = this.getRoles();
126         final StringBuffer rolesBuffer = new StringBuffer();
127         boolean first = true;
128         for (final Iterator userIterator = users.iterator(); userIterator.hasNext();)
129         {
130             if (first)
131             {
132                 first = false;
133             }
134             else
135             {
136                 rolesBuffer.append(',');
137             }
138             final Role role = (Role)userIterator.next();
139             rolesBuffer.append(role.getName());
140         }
141         return rolesBuffer.toString();
142     }
143 
144     public Collection getOperations()
145     {
146         return Collections.EMPTY_LIST;
147     }
148 
149     protected List handleGetPages()
150     {
151         return this.getViews();
152     }
153 
154     protected List handleGetAllPages()
155     {
156         final List pagesList = new ArrayList();
157         final Collection allActionStates = getModel().getAllActionStates();
158 
159         for (final Iterator actionStateIterator = allActionStates.iterator(); actionStateIterator.hasNext();)
160         {
161             final Object actionState = actionStateIterator.next();
162             if (actionState instanceof StrutsJsp)
163                 pagesList.add(actionState);
164         }
165         return pagesList;
166     }
167 
168     protected List handleGetFormFields()
169     {
170         final List formFields = new ArrayList(); // parameter names are supposed to be unique
171 
172         final Collection pages = getPages();
173         for (final Iterator pageIterator = pages.iterator(); pageIterator.hasNext();)
174         {
175             final StrutsJsp jsp = (StrutsJsp)pageIterator.next();
176             final Collection variables = jsp.getPageVariables();
177             for (final Iterator variableIterator = variables.iterator(); variableIterator.hasNext();)
178             {
179                 formFields.add(variableIterator.next());
180             }
181             final Collection parameters = jsp.getAllActionParameters();
182             for (final Iterator parameterIterator = parameters.iterator(); parameterIterator.hasNext();)
183             {
184                 formFields.add(parameterIterator.next());
185             }
186         }
187         return formFields;
188     }
189 
190     protected boolean handleIsValidationRequired()
191     {
192         final Collection allPages = this.getAllPages();
193         for (final Iterator iterator = allPages.iterator(); iterator.hasNext();)
194         {
195             final StrutsJsp jsp = (StrutsJsp)iterator.next();
196             if (jsp.isValidationRequired())
197             {
198                 return true;
199             }
200         }
201         return false;
202     }
203 
204     protected boolean handleIsApplicationValidationRequired()
205     {
206         final Collection useCases = this.getAllUseCases();
207         for (final Iterator iterator = useCases.iterator(); iterator.hasNext();)
208         {
209             final StrutsUseCase useCase = (StrutsUseCase)iterator.next();
210             if (useCase.isValidationRequired())
211             {
212                 return true;
213             }
214         }
215         return false;
216     }
217 
218     /**
219      * Overriden because StrutsAction does not extend FrontEndAction.
220      *
221      * @see org.andromda.metafacades.uml.FrontEndUseCase#getActions()
222      */
223     public List getActions()
224     {
225         final Collection actions = new LinkedHashSet();
226 
227         final Collection pages = getPages();
228         for (final Iterator pageIterator = pages.iterator(); pageIterator.hasNext();)
229         {
230             final StrutsJsp jsp = (StrutsJsp)pageIterator.next();
231             actions.addAll(jsp.getActions());
232         }
233 
234         final StrutsActivityGraph graph = (StrutsActivityGraph)getActivityGraph();
235         if (graph != null)
236         {
237             final StrutsAction action = graph.getFirstAction();
238             if (action != null) actions.add(action);
239         }
240 
241         return new ArrayList(actions);
242     }
243 
244     protected List handleGetPageVariables()
245     {
246         return this.getViewVariables();
247     }
248 
249     protected boolean handleIsApplicationUseCase()
250     {
251         return this.isEntryUseCase();
252     }
253 
254     protected String handleGetCssFileName()
255     {
256         return this.getPackagePath() + '/' + Bpm4StrutsUtils.toWebFileName(this.getName()) + ".css";
257     }
258 
259     protected TreeNode handleGetApplicationHierarchyRoot()
260     {
261         final UseCaseNode root = new UseCaseNode(this);
262         this.createHierarchy(root);
263         return root;
264     }
265 
266     protected TreeNode handleGetHierarchyRoot()
267     {
268         UseCaseNode hierarchy = null;
269 
270         final Collection allUseCases = this.getAllUseCases();
271         for (final Iterator useCaseIterator = allUseCases.iterator(); useCaseIterator.hasNext();)
272         {
273             final StrutsUseCase useCase = (StrutsUseCase)useCaseIterator.next();
274             if (useCase.isApplicationUseCase())
275             {
276                 final UseCaseNode root = (UseCaseNode)useCase.getApplicationHierarchyRoot();
277                 hierarchy = this.findNode(root, this);
278             }
279         }
280         return hierarchy;
281     }
282 
283     /**
284      * Recursively creates a hierarchy of use-cases, starting with the argument use-case as the root. This is primarily
285      * meant to build a set of menu items.
286      */
287     private void createHierarchy(UseCaseNode root)
288     {
289         final StrutsUseCase useCase = (StrutsUseCase)root.getUserObject();
290 
291         final FrontEndActivityGraph graph = useCase.getActivityGraph();
292         if (graph != null)
293         {
294             final Collection finalStates = graph.getFinalStates();
295             for (final Iterator finalStateIterator = finalStates.iterator(); finalStateIterator.hasNext();)
296             {
297                 final StrutsFinalState finalState = (StrutsFinalState)finalStateIterator.next();
298                 final StrutsUseCase targetUseCase = (StrutsUseCase)finalState.getTargetUseCase();
299                 if (targetUseCase != null)
300                 {
301                     final UseCaseNode useCaseNode = new UseCaseNode(targetUseCase);
302                     if (!isNodeAncestor(root, useCaseNode))
303                     {
304                         root.add(useCaseNode);
305                         createHierarchy(useCaseNode);
306                     }
307                 }
308             }
309         }
310     }
311 
312     /**
313      * <code>true</code> if the argument ancestor node is actually an ancestor of the first node.
314      * <p>
315      * <em>Note: DefaultMutableTreeNode's isNodeAncestor does not work because of its specific impl.</em>
316      */
317     private boolean isNodeAncestor(
318         UseCaseNode node,
319         UseCaseNode ancestorNode)
320     {
321         boolean ancestor = false;
322 
323         if (node.getUseCase().equals(ancestorNode.getUseCase()))
324         {
325             ancestor = true;
326         }
327         while (!ancestor && node.getParent() != null)
328         {
329             node = (UseCaseNode)node.getParent();
330             if (this.isNodeAncestor(node, ancestorNode))
331             {
332                 ancestor = true;
333             }
334         }
335         return ancestor;
336     }
337 
338     /**
339      * Given a root use-case, finds the node in the hierarchy that represent the argument StrutsUseCase node.
340      */
341     private UseCaseNode findNode(
342         UseCaseNode root,
343         StrutsUseCase useCase)
344     {
345         UseCaseNode useCaseNode = null;
346 
347         final List nodeList = Collections.list(root.breadthFirstEnumeration());
348         for (final Iterator nodeIterator = nodeList.iterator(); nodeIterator.hasNext() && useCaseNode == null;)
349         {
350             UseCaseNode node = (UseCaseNode)nodeIterator.next();
351             if (useCase.equals(node.getUserObject()))
352             {
353                 useCaseNode = node;
354             }
355         }
356         return useCaseNode;
357     }
358 
359     public final static class UseCaseNode
360         extends DefaultMutableTreeNode
361     {
362         public UseCaseNode(StrutsUseCase useCase)
363         {
364             super(useCase);
365         }
366 
367         public StrutsUseCase getUseCase()
368         {
369             return (StrutsUseCase)getUserObject();
370         }
371     }
372 
373     private boolean normalizeMessages()
374     {
375         final String normalizeMessages = (String)getConfiguredProperty(Bpm4StrutsGlobals.PROPERTY_NORMALIZE_MESSAGES);
376         return Boolean.valueOf(normalizeMessages).booleanValue();
377     }
378 
379     protected Map handleGetAllMessages()
380     {
381         final boolean normalize = this.normalizeMessages();
382         final Map messages = (normalize) ? (Map)new TreeMap() : (Map)new LinkedHashMap();
383 
384         if (this.isApplicationUseCase())
385         {
386             final List useCases = this.getAllUseCases();
387             for (int i = 0; i < useCases.size(); i++)
388             {
389                 // USECASE
390                 final StrutsUseCase useCase = (StrutsUseCase)useCases.get(i);
391                 messages.put(useCase.getTitleKey(), useCase.getTitleValue());
392                 messages.put(useCase.getOnlineHelpKey(), useCase.getOnlineHelpValue());
393 
394                 final List actions = useCase.getActions();
395                 for (int j = 0; j < actions.size(); j++)
396                 {
397                     final StrutsAction action = (StrutsAction)actions.get(j);
398 
399                     // FORWARDS
400                     final List transitions = action.getTransitions();
401                     for (int l = 0; l < transitions.size(); l++)
402                     {
403                         final StrutsForward forward = (StrutsForward)transitions.get(l);
404                         messages.putAll(forward.getSuccessMessages());
405                         messages.putAll(forward.getWarningMessages());
406                     }
407 
408                     // EXCEPTION FORWARDS
409                     final List exceptions = action.getActionExceptions();
410 
411                     if (normalize)
412                     {
413                         if (exceptions.isEmpty())
414                         {
415                             if (!action.isUseCaseStart())
416                             {
417                                 messages.put(action.getMessageKey() + ".exception", "{0} (java.lang.Exception)");
418                             }
419                         }
420                         else
421                         {
422                             for (int l = 0; l < exceptions.size(); l++)
423                             {
424                                 final StrutsExceptionHandler exception = (StrutsExceptionHandler)exceptions.get(l);
425                                 messages.put(action.getMessageKey() + '.' + exception.getExceptionKey(), "{0}");
426                             }
427                         }
428                     }
429                     else
430                     {
431                         if (exceptions.isEmpty())
432                         {
433                             if (!action.isUseCaseStart())
434                             {
435                                 messages.put(action.getMessageKey() + ".exception", "{0} (java.lang.Exception)");
436                             }
437                         }
438                         else
439                         {
440                             for (int l = 0; l < exceptions.size(); l++)
441                             {
442                                 final StrutsExceptionHandler exception = (StrutsExceptionHandler)exceptions.get(l);
443                                 // we construct the key using the action message too because the exception can
444                                 // belong to more than one action (therefore it cannot return the correct value
445                                 // in .getExceptionKey())
446                                 messages.put(action.getMessageKey() + '.' + exception.getExceptionKey(),
447                                     "{0} (" + exception.getExceptionType() + ")");
448                             }
449                         }
450                     }
451 
452                     // TRIGGER
453                     final StrutsTrigger trigger = action.getActionTrigger();
454                     if (trigger != null)
455                     {
456                         // only add these when a trigger is present, otherwise it's no use having them
457                         messages.put(action.getOnlineHelpKey(), action.getOnlineHelpValue());
458                         messages.put(action.getDocumentationKey(), action.getDocumentationValue());
459 
460                         // the regular trigger messages
461                         messages.put(trigger.getTitleKey(), trigger.getTitleValue());
462                         messages.put(trigger.getNotAllowedTitleKey(), trigger.getNotAllowedTitleValue());
463                         messages.put(trigger.getResetMessageKey(), trigger.getResetMessageValue());
464                         messages.put(trigger.getResetNotAllowedTitleKey(), trigger.getResetNotAllowedTitleValue());
465                         messages.put(trigger.getResetTitleKey(), trigger.getResetTitleValue());
466                         // this one is the same as doing: action.getMessageKey()
467                         messages.put(trigger.getTriggerKey(), trigger.getTriggerValue());
468 
469                         // IMAGE LINK
470                         if (action.isImageLink())
471                         {
472                             messages.put(action.getImageMessageKey(), action.getImagePath());
473                         }
474                     }
475                 }
476 
477                 final List pages = useCase.getPages();
478                 for (int j = 0; j < pages.size(); j++)
479                 {
480                     // PAGE
481                     final StrutsJsp page = (StrutsJsp)pages.get(j);
482                     messages.put(page.getTitleKey(), page.getTitleValue());
483                     messages.put(page.getMessageKey(), page.getMessageValue());
484                     messages.put(page.getOnlineHelpKey(), page.getOnlineHelpValue());
485                     messages.put(page.getDocumentationKey(), page.getDocumentationValue());
486 
487                     final List pageVariables = page.getPageVariables();
488                     for (int k = 0; k < pageVariables.size(); k++)
489                     {
490                         // PAGE-VARIABLE
491                         final StrutsParameter parameter = (StrutsParameter)pageVariables.get(k);
492 
493                         messages.put(parameter.getMessageKey(), parameter.getMessageValue());
494 /*
495                         if (normalize)
496                         {
497                             // the next line is in comment because it's not actually being used
498                             //messages.put(parameter.getTitleKey(), parameter.getTitleValue());
499                             messages.put(parameter.getMessageKey(), parameter.getMessageValue());
500                         }
501                         else
502                         {
503                             // the next line is in comment because it's not actually being used
504                             //messages.put(page.getTitleKey() + '.' + parameter.getTitleKey(), parameter.getTitleValue());
505                             messages.put(page.getTitleKey() + '.' + parameter.getMessageKey(),
506                                     parameter.getMessageValue());
507                         }
508 */
509 
510                         // TABLE
511                         if (parameter.isTable())
512                         {
513                             final Collection columnNames = parameter.getTableColumnNames();
514                             for (final Iterator columnNameIterator = columnNames.iterator();
515                                  columnNameIterator.hasNext();)
516                             {
517                                 final String columnName = (String)columnNameIterator.next();
518                                 messages.put(parameter.getTableColumnMessageKey(columnName),
519                                     parameter.getTableColumnMessageValue(columnName));
520                             }
521                         }
522                     }
523 
524                     for (int k = 0; k < actions.size(); k++)
525                     {
526                         // ACTION
527                         final StrutsAction action = (StrutsAction)actions.get(k);
528 
529                         // ACTION PARAMETERS
530                         final List parameters = action.getActionParameters();
531                         for (int l = 0; l < parameters.size(); l++)
532                         {
533                             final StrutsParameter parameter = (StrutsParameter)parameters.get(l);
534                             messages.put(parameter.getMessageKey(), parameter.getMessageValue());
535                             messages.put(parameter.getOnlineHelpKey(), parameter.getOnlineHelpValue());
536                             messages.put(parameter.getDocumentationKey(), parameter.getDocumentationValue());
537                             messages.put(parameter.getTitleKey(), parameter.getTitleValue());
538 
539                             if (parameter.getValidWhen() != null)
540                             {
541                                 // this key needs to be fully qualified since the valid when value can be different
542                                 final String completeKeyPrefix = (normalize)
543                                     ? parameter.getMessageKey()
544                                     : useCase.getTitleKey() + '.' +
545                                     page.getMessageKey() + '.' +
546                                     action.getMessageKey() + '.' +
547                                     parameter.getMessageKey();
548                                 messages.put(completeKeyPrefix + "_validwhen",
549                                     "{0} is only valid when " + parameter.getValidWhen());
550                             }
551 
552                             if (parameter.getOptionCount() > 0)
553                             {
554                                 final List optionKeys = parameter.getOptionKeys();
555                                 final List optionValues = parameter.getOptionValues();
556 
557                                 for (int m = 0; m < optionKeys.size(); m++)
558                                 {
559                                     messages.put(optionKeys.get(m), optionValues.get(m));
560                                     messages.put(optionKeys.get(m) + ".title", optionValues.get(m));
561                                 }
562                             }
563                         }
564                     }
565                 }
566             }
567         }
568 
569         return messages;
570     }
571 
572     protected String handleGetOnlineHelpPagePath()
573     {
574         final StringBuffer buffer = new StringBuffer();
575 
576         if (StringUtils.isNotBlank(this.getPackagePath()))
577         {
578             buffer.append('/');
579             buffer.append(this.getPackagePath());
580         }
581         buffer.append('/');
582         buffer.append(StringUtilsHelper.separate(this.getName(), "-"));
583         buffer.append("_help");
584 
585         return buffer.toString();
586     }
587 
588     protected String handleGetOnlineHelpActionPath()
589     {
590         final StringBuffer buffer = new StringBuffer();
591 
592         if (StringUtils.isNotBlank(this.getPackagePath()))
593         {
594             buffer.append('/');
595             buffer.append(this.getPackagePath());
596         }
597         buffer.append('/');
598         buffer.append(StringUtilsHelper.upperCamelCaseName(this.getName()));
599         buffer.append("Help");
600 
601         return buffer.toString();
602     }
603 
604     /**
605      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsUseCase#getFormKey()
606      */
607     protected String handleGetFormKey()
608     {
609         final Object formKeyValue = this.findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_ACTION_FORM_KEY);
610         return formKeyValue == null
611             ? Bpm4StrutsProfile.TAGGEDVALUE_ACTION_FORM_DEFAULT_KEY
612             : String.valueOf(formKeyValue);
613     }
614 
615 }