1 package org.andromda.cartridges.jsf.metafacades;
2
3 import java.security.MessageDigest;
4 import java.security.NoSuchAlgorithmException;
5 import java.util.ArrayList;
6 import java.util.Collection;
7 import java.util.Collections;
8 import java.util.Iterator;
9 import java.util.LinkedHashMap;
10 import java.util.List;
11 import java.util.Map;
12 import org.andromda.cartridges.jsf.JSFGlobals;
13 import org.andromda.cartridges.jsf.JSFProfile;
14 import org.andromda.cartridges.jsf.JSFUtils;
15 import org.andromda.metafacades.uml.EventFacade;
16 import org.andromda.metafacades.uml.FrontEndAction;
17 import org.andromda.metafacades.uml.FrontEndActionState;
18 import org.andromda.metafacades.uml.FrontEndControllerOperation;
19 import org.andromda.metafacades.uml.FrontEndForward;
20 import org.andromda.metafacades.uml.FrontEndParameter;
21 import org.andromda.metafacades.uml.FrontEndView;
22 import org.andromda.metafacades.uml.ModelElementFacade;
23 import org.andromda.metafacades.uml.UseCaseFacade;
24 import org.andromda.utils.StringUtilsHelper;
25 import org.apache.commons.collections.CollectionUtils;
26 import org.apache.commons.collections.Predicate;
27 import org.apache.commons.lang.ObjectUtils;
28 import org.apache.commons.lang.StringUtils;
29 import org.apache.log4j.Logger;
30
31
32
33
34
35
36 public class JSFActionLogicImpl
37 extends JSFActionLogic
38 {
39 private static final long serialVersionUID = 34L;
40
41
42
43
44 public JSFActionLogicImpl(
45 Object metaObject,
46 String context)
47 {
48 super(metaObject, context);
49 }
50
51
52
53
54 private static final Logger LOGGER = Logger.getLogger(JSFActionLogicImpl.class);
55
56
57
58
59
60 protected String handleGetFormBeanName()
61 {
62 return this.getFormBeanName(true);
63 }
64
65
66
67
68
69
70
71 private String getFormBeanName(boolean withUseCaseName)
72 {
73 final String pattern = ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.FORM_BEAN_PATTERN));
74 final ModelElementFacade useCase = this.getUseCase();
75 final String useCaseName = withUseCaseName && useCase != null
76 ? StringUtilsHelper.lowerCamelCaseName(useCase.getName()) : "";
77 final String formBeanName = pattern.replaceFirst("\\{0\\}", useCaseName);
78 final String triggerName = !pattern.equals(formBeanName)
79 ? StringUtils.capitalize(this.getTriggerName()) : this.getTriggerName();
80 return formBeanName.replaceFirst(
81 "\\{1\\}",
82 triggerName);
83 }
84
85
86
87
88 public String getName()
89 {
90 return JSFUtils.toWebResourceName(this.getUseCase().getName() + "-" + super.getName());
91 }
92
93
94
95
96
97 protected String handleGetTriggerName()
98 {
99 String name = null;
100 if (this.isExitingInitialState())
101 {
102 final JSFUseCase useCase = (JSFUseCase)this.getUseCase();
103 if (useCase != null)
104 {
105 name = useCase.getName();
106 }
107 }
108 else
109 {
110 final EventFacade trigger = this.getTrigger();
111 final String suffix = trigger == null ? this.getTarget().getName() : trigger.getName();
112 name = this.getSource().getName() + ' ' + suffix;
113 }
114 return StringUtilsHelper.lowerCamelCaseName(name);
115 }
116
117
118
119
120
121 protected String handleGetFormImplementationName()
122 {
123 final String pattern =
124 ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.FORM_IMPLEMENTATION_PATTERN));
125 return pattern.replaceFirst(
126 "\\{0\\}",
127 StringUtils.capitalize(this.getTriggerName()));
128 }
129
130
131
132
133
134 protected boolean handleIsTableAction()
135 {
136 return JSFGlobals.ACTION_TYPE_TABLE.equals(this.findTaggedValue(JSFProfile.TAGGEDVALUE_ACTION_TYPE));
137 }
138
139
140
141
142
143 protected String handleGetFullyQualifiedFormImplementationName()
144 {
145 final StringBuilder fullyQualifiedName = new StringBuilder();
146 final String packageName = this.getPackageName();
147 if (StringUtils.isNotBlank(packageName))
148 {
149 fullyQualifiedName.append(packageName + '.');
150 }
151 return fullyQualifiedName.append(this.getFormImplementationName()).toString();
152 }
153
154
155
156
157
158 protected String handleGetFullyQualifiedFormImplementationPath()
159 {
160 return this.getFullyQualifiedFormImplementationName().replace(
161 '.',
162 '/');
163 }
164
165
166
167
168
169 protected String handleGetFormScope()
170 {
171 String scope = ObjectUtils.toString(this.findTaggedValue(JSFProfile.TAGGEDVALUE_ACTION_FORM_SCOPE));
172 if (StringUtils.isEmpty(scope))
173 {
174 scope = ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.FORM_SCOPE));
175 }
176 return scope;
177 }
178
179
180
181
182
183 protected String handleGetFormImplementationInterfaceList()
184 {
185 final List<FrontEndControllerOperation> deferredOperations = this.getDeferredOperations();
186 for (final Iterator<FrontEndControllerOperation> iterator = deferredOperations.iterator(); iterator.hasNext();)
187 {
188
189 final JSFControllerOperation operation = (JSFControllerOperation)iterator.next();
190 if (operation != null && operation.getArguments() != null && operation.getArguments().isEmpty())
191 {
192 iterator.remove();
193 }
194 }
195 final StringBuilder list = new StringBuilder();
196 for (final Iterator<FrontEndControllerOperation> iterator = deferredOperations.iterator(); iterator.hasNext();)
197 {
198 final JSFControllerOperation operation = (JSFControllerOperation)iterator.next();
199 if (operation != null)
200 {
201 list.append(operation.getFormName());
202 if (iterator.hasNext())
203 {
204 list.append(", ");
205 }
206 }
207 }
208 return list.toString();
209 }
210
211
212
213
214 protected String handleGetPath()
215 {
216 String path = this.getPathRoot() + '/' + JSFUtils.toWebResourceName(this.getTriggerName());
217 if (this.isExitingInitialState())
218 {
219 final JSFUseCase useCase = (JSFUseCase)this.getUseCase();
220 if (useCase != null && useCase.isViewHasNameOfUseCase())
221 {
222
223
224
225 path = path + "uc";
226 }
227 }
228 return path;
229 }
230
231
232
233
234
235 protected String handleGetPathRoot()
236 {
237 final StringBuilder pathRoot = new StringBuilder();
238 final JSFUseCase useCase = (JSFUseCase)this.getUseCase();
239 if (useCase != null)
240 {
241 pathRoot.append(useCase.getPathRoot());
242 }
243 return pathRoot.toString();
244 }
245
246
247
248
249
250 protected String handleGetMessageKey()
251 {
252 String messageKey = null;
253
254 final Object trigger = this.getTrigger();
255 if (trigger instanceof JSFEvent)
256 {
257 final JSFEvent actionTrigger = (JSFEvent)trigger;
258 messageKey = actionTrigger.getMessageKey();
259 }
260 return messageKey;
261 }
262
263
264
265
266
267 protected String handleGetDocumentationKey()
268 {
269 final Object trigger = this.getTrigger();
270 JSFEvent event = null;
271 if (trigger instanceof JSFEvent)
272 {
273 event = (JSFEvent)trigger;
274 }
275 return (event == null ? this.getMessageKey() + ".is.an.action.without.trigger" : event.getMessageKey()) +
276 '.' + JSFGlobals.DOCUMENTATION_MESSAGE_KEY_SUFFIX;
277 }
278
279
280
281
282
283 protected String handleGetDocumentationValue()
284 {
285 final String value = StringUtilsHelper.toResourceMessage(getDocumentation(
286 "",
287 64,
288 false));
289 return value == null ? "" : value;
290 }
291
292
293
294
295
296 protected String handleGetViewFragmentPath()
297 {
298 return '/' + this.getPackageName().replace(
299 '.',
300 '/') + '/' + JSFUtils.toWebResourceName(this.getTriggerName());
301 }
302
303
304
305
306
307 protected String handleGetTableLinkName()
308 {
309 String tableLink = null;
310
311 final Object value = findTaggedValue(JSFProfile.TAGGEDVALUE_ACTION_TABLELINK);
312 if (value != null)
313 {
314 tableLink = StringUtils.trimToNull(value.toString());
315
316 if (tableLink != null)
317 {
318 final int columnOffset = tableLink.indexOf('.');
319 tableLink = columnOffset == -1 ? tableLink : tableLink.substring(
320 0,
321 columnOffset);
322 }
323 }
324
325 return tableLink;
326 }
327
328
329
330
331
332 protected String handleGetTableLinkColumnName()
333 {
334 String tableLink = null;
335 final Object value = findTaggedValue(JSFProfile.TAGGEDVALUE_ACTION_TABLELINK);
336 if (value != null)
337 {
338 tableLink = StringUtils.trimToNull(value.toString());
339
340 if (tableLink != null)
341 {
342 final int columnOffset = tableLink.indexOf('.');
343 tableLink = (columnOffset == -1 || columnOffset == tableLink.length() - 1)
344 ? null : tableLink.substring(columnOffset + 1);
345 }
346 }
347 return tableLink;
348 }
349
350
351
352
353
354 protected Object handleGetTableLinkParameter()
355 {
356 JSFParameter tableLinkParameter = null;
357 final String tableLinkName = this.getTableLinkName();
358 if (tableLinkName != null)
359 {
360 final JSFView view = (JSFView)this.getInput();
361 if (view != null)
362 {
363 final List<FrontEndParameter> tables = view.getTables();
364 for (int ctr = 0; ctr < tables.size() && tableLinkParameter == null; ctr++)
365 {
366 final Object object = tables.get(ctr);
367 if (object instanceof JSFParameter)
368 {
369 final JSFParameter table = (JSFParameter)object;
370 if (tableLinkName.equals(table.getName()))
371 {
372 tableLinkParameter = table;
373 }
374 }
375 }
376 }
377 }
378 return tableLinkParameter;
379 }
380
381
382
383
384
385 protected boolean handleIsTableLink()
386 {
387 return this.getTableLinkParameter() != null;
388 }
389
390
391
392
393
394 protected boolean handleIsHyperlink()
395 {
396 final Object value = findTaggedValue(JSFProfile.TAGGEDVALUE_ACTION_TYPE);
397 return JSFGlobals.ACTION_TYPE_HYPERLINK.equalsIgnoreCase(value == null ? null : value.toString());
398 }
399
400
401
402
403
404 protected String handleGetActionClassName()
405 {
406 return StringUtilsHelper.upperCamelCaseName(this.getTriggerName());
407 }
408
409
410
411
412
413 protected String handleGetFullyQualifiedActionClassPath()
414 {
415 return this.getFullyQualifiedActionClassName().replace(
416 '.',
417 '/') + ".java";
418 }
419
420
421
422
423
424
425 public String getPackageName()
426 {
427 final UseCaseFacade useCase = this.getUseCase();
428 return useCase != null ? useCase.getPackageName() : "";
429 }
430
431
432
433
434
435 protected String handleGetControllerAction()
436 {
437 return this.getTriggerName();
438 }
439
440
441
442
443
444 protected String handleGetFullyQualifiedActionClassName()
445 {
446 final StringBuilder path = new StringBuilder();
447 final JSFUseCase useCase = (JSFUseCase)this.getUseCase();
448 if (useCase != null)
449 {
450 final String packageName = useCase.getPackageName();
451 if (StringUtils.isNotBlank(packageName))
452 {
453 path.append(packageName);
454 path.append('.');
455 }
456 }
457 path.append(this.getActionClassName());
458 return path.toString();
459 }
460
461
462
463
464
465 protected boolean handleIsResettable()
466 {
467 final Object value = findTaggedValue(JSFProfile.TAGGEDVALUE_ACTION_RESETTABLE);
468 return this.isTrue(value == null ? null : value.toString());
469 }
470
471
472
473
474 private boolean isTrue(String string)
475 {
476 return "yes".equalsIgnoreCase(string) || "true".equalsIgnoreCase(string) || "on".equalsIgnoreCase(string) ||
477 "1".equalsIgnoreCase(string);
478 }
479
480
481
482
483 protected List<FrontEndAction> handleGetOtherUseCaseFormActions()
484 {
485 final List<FrontEndAction> otherActions = new ArrayList<FrontEndAction>(this.getUseCase().getActions());
486 for (final Iterator<FrontEndAction> iterator = otherActions.iterator(); iterator.hasNext();)
487 {
488 final FrontEndAction action = iterator.next();
489
490
491 if (action.equals(this.THIS()) || action.getFormFields().isEmpty())
492 {
493 iterator.remove();
494 }
495 }
496 return otherActions;
497 }
498
499
500
501
502
503 protected String handleGetFormKey()
504 {
505 final Object formKeyValue = this.findTaggedValue(JSFProfile.TAGGEDVALUE_ACTION_FORM_KEY);
506 return formKeyValue == null ? ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.ACTION_FORM_KEY))
507 : String.valueOf(formKeyValue);
508 }
509
510
511
512
513
514 protected List<FrontEndParameter> handleGetHiddenParameters()
515 {
516 final List<FrontEndParameter> hiddenParameters = new ArrayList<FrontEndParameter>(this.getParameters());
517 CollectionUtils.filter(
518 hiddenParameters,
519 new Predicate()
520 {
521 public boolean evaluate(final Object object)
522 {
523 boolean valid = false;
524 if (object instanceof JSFParameter)
525 {
526 final JSFParameter parameter = (JSFParameter)object;
527 valid = parameter.isInputHidden();
528 if (!valid)
529 {
530 for (final Iterator iterator = parameter.getAttributes().iterator(); iterator.hasNext();)
531 {
532 JSFAttribute attribute = (JSFAttribute)iterator.next();
533 valid = attribute.isInputHidden();
534 if (valid)
535 {
536 break;
537 }
538 }
539 }
540 }
541 return valid;
542 }
543 });
544 return hiddenParameters;
545 }
546
547
548
549
550
551 protected boolean handleIsValidationRequired()
552 {
553 boolean required = false;
554 for (final FrontEndParameter frontEndParam : this.getParameters())
555 {
556 if (frontEndParam instanceof JSFParameter)
557 {
558 final JSFParameter parameter = (JSFParameter)frontEndParam;
559 if (parameter.isValidationRequired())
560 {
561 required = true;
562 break;
563 }
564 }
565 }
566 return required;
567 }
568
569
570
571
572
573 protected boolean handleIsPopup()
574 {
575 boolean popup = ObjectUtils.toString(this.findTaggedValue(JSFProfile.TAGGEDVALUE_ACTION_TYPE)).equalsIgnoreCase(
576 JSFGlobals.VIEW_TYPE_POPUP);
577 if (!popup)
578 {
579 for (final FrontEndView feView : this.getTargetViews())
580 {
581 final JSFView view = (JSFView)feView;
582 popup = view.isPopup();
583 if (!popup)
584 {
585 break;
586 }
587 }
588 }
589 return popup;
590 }
591
592
593
594
595
596 protected boolean handleIsFormResetRequired()
597 {
598 boolean resetRequired = this.isFormReset();
599 if (!resetRequired)
600 {
601 for (final FrontEndParameter feParameter : this.getParameters())
602 {
603 if (feParameter instanceof JSFParameter)
604 {
605 final JSFParameter parameter = (JSFParameter)feParameter;
606 resetRequired = parameter.isReset();
607 if (resetRequired)
608 {
609 break;
610 }
611 }
612 }
613 }
614 return resetRequired;
615 }
616
617
618
619
620
621
622 public FrontEndView getInput()
623 {
624 FrontEndView input = null;
625 final ModelElementFacade source = this.getSource();
626 if (source instanceof FrontEndView)
627 {
628 input = (FrontEndView)source;
629 }
630 return input;
631 }
632
633
634
635
636
637 protected String handleGetFormSerialVersionUID()
638 {
639 final StringBuilder buffer = new StringBuilder();
640
641 buffer.append(this.getName());
642
643 final ModelElementFacade input = (ModelElementFacade)this.getInput();
644 buffer.append(input != null ? input.getName() : "");
645
646 final ModelElementFacade guard = this.getGuard();
647 buffer.append(guard != null ? guard.getName() : "");
648
649 final ModelElementFacade effect = this.getEffect();
650 buffer.append(effect != null ? effect.getName() : "");
651
652 final ModelElementFacade decisionsTrigger = this.getDecisionTrigger();
653 buffer.append(decisionsTrigger != null ? decisionsTrigger.getName() : "");
654
655 buffer.append(StringUtils.trimToEmpty(this.getActionClassName()));
656
657 for (final FrontEndParameter parameter : this.getParameters())
658 {
659 buffer.append(parameter.getName());
660 }
661
662 for (final FrontEndForward forward : this.getActionForwards())
663 {
664 buffer.append(forward.getName());
665 }
666
667 for (final FrontEndAction action : this.getActions())
668 {
669 buffer.append(action.getName());
670 }
671
672 for (final FrontEndActionState state : this.getActionStates())
673 {
674 buffer.append(state.getName());
675 }
676 final String signature = buffer.toString();
677
678 String serialVersionUID = String.valueOf(0L);
679 try
680 {
681 MessageDigest md = MessageDigest.getInstance("SHA");
682 byte[] hashBytes = md.digest(signature.getBytes());
683
684 long hash = 0;
685 for (int ctr = Math.min(
686 hashBytes.length,
687 8) - 1; ctr >= 0; ctr--)
688 {
689 hash = (hash << 8) | (hashBytes[ctr] & 0xFF);
690 }
691 serialVersionUID = String.valueOf(hash);
692 }
693 catch (final NoSuchAlgorithmException exception)
694 {
695 final String message = "Error performing JSFAction.getFormSerialVersionUID";
696 LOGGER.error(
697 message,
698 exception);
699 }
700 return serialVersionUID;
701 }
702
703
704
705
706
707 protected boolean handleIsFormReset()
708 {
709 return Boolean.valueOf(ObjectUtils.toString(this.findTaggedValue(
710 JSFProfile.TAGGEDVALUE_ACTION_FORM_RESET))).booleanValue();
711 }
712
713
714
715
716
717 protected String handleGetFormImplementationGetter()
718 {
719 return "get" + StringUtils.capitalize(this.getFormBeanName(false)) + "()";
720 }
721
722
723
724
725
726 protected boolean handleIsFinalStateTarget()
727 {
728 return this.getTarget() instanceof JSFFinalState;
729 }
730
731
732
733
734
735 protected String handleGetFromOutcome()
736 {
737 return this.getName();
738 }
739
740
741
742
743 protected boolean handleIsSuccessMessagesPresent()
744 {
745 return !this.getSuccessMessages().isEmpty();
746 }
747
748
749
750
751 protected boolean handleIsWarningMessagesPresent()
752 {
753 return !this.getWarningMessages().isEmpty();
754 }
755
756
757
758
759
760
761
762
763 private Map<String, String> getMessages(String taggedValue)
764 {
765 Map<String, String> messages;
766
767 final Collection taggedValues = this.findTaggedValues(taggedValue);
768 if (taggedValues.isEmpty())
769 {
770 messages = Collections.EMPTY_MAP;
771 }
772 else
773 {
774 messages = new LinkedHashMap<String, String>();
775 for (final Object tag : taggedValues)
776 {
777 final String value = (String)tag;
778 messages.put(StringUtilsHelper.toResourceMessageKey(value), value);
779 }
780 }
781
782 return messages;
783 }
784
785
786
787
788 protected Map<String, String> handleGetSuccessMessages()
789 {
790 return this.getMessages(JSFProfile.TAGGEDVALUE_ACTION_SUCCESS_MESSAGE);
791 }
792
793
794
795
796 protected Map<String, String> handleGetWarningMessages()
797 {
798 return this.getMessages(JSFProfile.TAGGEDVALUE_ACTION_WARNING_MESSAGE);
799 }
800
801
802
803
804
805 protected boolean handleIsNeedsFileUpload()
806 {
807 if(this.getParameters().size() == 0)
808 {
809 return false;
810 }
811
812 for (final FrontEndParameter feParameter : this.getParameters())
813 {
814 if (feParameter instanceof JSFParameter)
815 {
816 final JSFParameter parameter = (JSFParameter)feParameter;
817 if(parameter.isInputFile())
818 {
819 return true;
820 }
821 if(parameter.isComplex())
822 {
823 for(final Iterator attributes = parameter.getAttributes().iterator(); attributes.hasNext();)
824 if(((JSFAttribute)attributes.next()).isInputFile())
825 return true;
826 }
827 }
828 }
829 return false;
830 }
831
832
833
834
835 @Override
836 protected String handleGetTriggerMethodName()
837 {
838 final StringBuilder methodName = new StringBuilder();
839 if (this.isExitingInitialState())
840 {
841 final JSFUseCase useCase = (JSFUseCase)this.getUseCase();
842 methodName.append(StringUtilsHelper.lowerCamelCaseName(useCase.getName())+"_started");
843 }
844 else
845 {
846 methodName.append(StringUtilsHelper.lowerCamelCaseName(this.getSource().getName()));
847 methodName.append('_');
848 final EventFacade trigger = this.getTrigger();
849 final String suffix = trigger == null ? this.getTarget().getName() : trigger.getName();
850 methodName.append(StringUtilsHelper.lowerCamelCaseName(suffix));
851 }
852 return "_"+methodName.toString();
853 }
854 }