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();
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
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
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
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
444
445
446 messages.put(action.getMessageKey() + '.' + exception.getExceptionKey(),
447 "{0} (" + exception.getExceptionType() + ")");
448 }
449 }
450 }
451
452
453 final StrutsTrigger trigger = action.getActionTrigger();
454 if (trigger != null)
455 {
456
457 messages.put(action.getOnlineHelpKey(), action.getOnlineHelpValue());
458 messages.put(action.getDocumentationKey(), action.getDocumentationValue());
459
460
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
467 messages.put(trigger.getTriggerKey(), trigger.getTriggerValue());
468
469
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
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
491 final StrutsParameter parameter = (StrutsParameter)pageVariables.get(k);
492
493 messages.put(parameter.getMessageKey(), parameter.getMessageValue());
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
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
527 final StrutsAction action = (StrutsAction)actions.get(k);
528
529
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
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 }