001package org.andromda.cartridges.jsf.metafacades;
002
003import java.security.MessageDigest;
004import java.security.NoSuchAlgorithmException;
005import java.util.ArrayList;
006import java.util.Collection;
007import java.util.Collections;
008import java.util.Iterator;
009import java.util.LinkedHashMap;
010import java.util.List;
011import java.util.Map;
012import org.andromda.cartridges.jsf.JSFGlobals;
013import org.andromda.cartridges.jsf.JSFProfile;
014import org.andromda.cartridges.jsf.JSFUtils;
015import org.andromda.metafacades.uml.EventFacade;
016import org.andromda.metafacades.uml.FrontEndAction;
017import org.andromda.metafacades.uml.FrontEndActionState;
018import org.andromda.metafacades.uml.FrontEndControllerOperation;
019import org.andromda.metafacades.uml.FrontEndForward;
020import org.andromda.metafacades.uml.FrontEndParameter;
021import org.andromda.metafacades.uml.FrontEndView;
022import org.andromda.metafacades.uml.ModelElementFacade;
023import org.andromda.metafacades.uml.UseCaseFacade;
024import org.andromda.utils.StringUtilsHelper;
025import org.apache.commons.collections.CollectionUtils;
026import org.apache.commons.collections.Predicate;
027import org.apache.commons.lang.ObjectUtils;
028import org.apache.commons.lang.StringUtils;
029import org.apache.log4j.Logger;
030
031/**
032 * MetafacadeLogic implementation for org.andromda.cartridges.jsf.metafacades.JSFAction.
033 *
034 * @see org.andromda.cartridges.jsf.metafacades.JSFAction
035 */
036public class JSFActionLogicImpl
037    extends JSFActionLogic
038{
039    private static final long serialVersionUID = 34L;
040    /**
041     * @param metaObject
042     * @param context
043     */
044    public JSFActionLogicImpl(
045        Object metaObject,
046        String context)
047    {
048        super(metaObject, context);
049    }
050
051    /**
052     * The logger instance.
053     */
054    private static final Logger LOGGER = Logger.getLogger(JSFActionLogicImpl.class);
055
056    /**
057     * @return getFormBeanName(true)
058     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFormBeanName()
059     */
060    protected String handleGetFormBeanName()
061    {
062        return this.getFormBeanName(true);
063    }
064
065    /**
066     * Constructs the form bean name, with our without prefixing the use case name.
067     *
068     * @param withUseCaseName whether or not to prefix the use case name.
069     * @return the constructed form bean name.
070     */
071    private String getFormBeanName(boolean withUseCaseName)
072    {
073        final String pattern = ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.FORM_BEAN_PATTERN));
074        final ModelElementFacade useCase = this.getUseCase();
075        final String useCaseName = withUseCaseName && useCase != null
076            ? StringUtilsHelper.lowerCamelCaseName(useCase.getName()) : "";
077        final String formBeanName = pattern.replaceFirst("\\{0\\}", useCaseName);
078        final String triggerName = !pattern.equals(formBeanName)
079            ? StringUtils.capitalize(this.getTriggerName()) : this.getTriggerName();
080        return formBeanName.replaceFirst(
081            "\\{1\\}",
082            triggerName);
083    }
084
085    /**
086     * @see org.andromda.metafacades.uml.ModelElementFacade#getName()
087     */
088    public String getName()
089    {
090        return JSFUtils.toWebResourceName(this.getUseCase().getName() + "-" + super.getName());
091    }
092
093    /**
094     * @return useCase.getName()
095     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getTriggerName()
096     */
097    protected String handleGetTriggerName()
098    {
099        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     * @return formImplementationName
119     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFormImplementationName()
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     * @return isTableAction
132     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFullyQualifiedFormImplementationName()
133     */
134    protected boolean handleIsTableAction()
135    {
136        return JSFGlobals.ACTION_TYPE_TABLE.equals(this.findTaggedValue(JSFProfile.TAGGEDVALUE_ACTION_TYPE));
137    }
138
139    /**
140     * @return fullyQualifiedFormImplementationName
141     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFullyQualifiedFormImplementationName()
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     * @return fullyQualifiedFormImplementationPath
156     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFullyQualifiedFormImplementationPath()
157     */
158    protected String handleGetFullyQualifiedFormImplementationPath()
159    {
160        return this.getFullyQualifiedFormImplementationName().replace(
161            '.',
162            '/');
163    }
164
165    /**
166     * @return scope
167     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFullyQualifiedFormImplementationPath()
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     * @return formImplementationInterfaceList
181     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFormImplementationInterfaceList()
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            // - remove any forms that don't have arguments
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     * @see org.andromda.cartridges.jsf.metafacades.JSFActionLogic#handleGetPath()
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                // - add the uc prefix to make the trigger name unique
223                //   when a view contained within the use case has the same name
224                //   as the use case
225                path = path + "uc";
226            }
227        }
228        return path;
229    }
230
231    /**
232     * @return pathRoot
233     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getPathRoot()
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     * @return messageKey
248     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getMessageKey()
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     * @return documentationKey
265     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getDocumentationKey()
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     * @return documentationValue
281     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getDocumentationValue()
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     * @return viewFragmentPath
294     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getViewFragmentPath()
295     */
296    protected String handleGetViewFragmentPath()
297    {
298        return '/' + this.getPackageName().replace(
299            '.',
300            '/') + '/' + JSFUtils.toWebResourceName(this.getTriggerName());
301    }
302
303    /**
304     * @return tableLink
305     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getTableLinkName()
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     * @return tableLink
330     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getTableLinkColumnName()
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     * @return tableLinkParameter
352     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#isTableLink()
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     * @return getTableLinkParameter() != null
383     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#isTableLink()
384     */
385    protected boolean handleIsTableLink()
386    {
387        return this.getTableLinkParameter() != null;
388    }
389
390    /**
391     * @return hyperlink
392     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#isHyperlink()
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     * @return StringUtilsHelper.upperCamelCaseName(this.getTriggerName())
402     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getActionClassName()
403     */
404    protected String handleGetActionClassName()
405    {
406        return StringUtilsHelper.upperCamelCaseName(this.getTriggerName());
407    }
408
409    /**
410     * @return fullyQualifiedActionClassPath
411     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFullyQualifiedActionClassPath()
412     */
413    protected String handleGetFullyQualifiedActionClassPath()
414    {
415        return this.getFullyQualifiedActionClassName().replace(
416            '.',
417            '/') + ".java";
418    }
419
420    /**
421     * Overridden to provide the owning use case's package name.
422     *
423     * @see org.andromda.metafacades.uml.ModelElementFacade#getPackageName()
424     */
425    public String getPackageName()
426    {
427        final UseCaseFacade useCase = this.getUseCase();
428        return useCase != null ? useCase.getPackageName() : "";
429    }
430
431    /**
432     * @return getTriggerName()
433     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getControllerAction()
434     */
435    protected String handleGetControllerAction()
436    {
437        return this.getTriggerName();
438    }
439
440    /**
441     * @return fullyQualifiedActionClassName
442     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFullyQualifiedActionClassName()
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     * @return findTaggedValue(JSFProfile.TAGGEDVALUE_ACTION_RESETTABLE) isTrue
463     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#isResettable()
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     * Convenient method to detect whether or not a String instance represents a boolean <code>true</code> value.
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     * @return otherActions
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            // - remove this action and any forms that don't have form fields
491            if (action.equals(this.THIS()) || action.getFormFields().isEmpty())
492            {
493                iterator.remove();
494            }
495        }
496        return otherActions;
497    }
498
499    /**
500     * @return hiddenParameters
501     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFormKey()
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     * @return hiddenParameters
512     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getHiddenParameters()
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     * @return required
549     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getHiddenParameters()
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     * @return popup
571     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#isPopup()
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     * @return resetRequired
594     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#isFormResetRequired()
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    //TODO remove after 3.4 release
618    /**
619     * Hack to keep the compatibility with Andromda 3.4
620     * @return getSource() instanceof FrontEndView
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     * @return formSerialVersionUID
635     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFormSerialVersionUID()
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     * @return findTaggedValue(JSFProfile.TAGGEDVALUE_ACTION_FORM_RESET)
705     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#isFormResetRequired()
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     * @return "get" + StringUtils.capitalize(this.getFormBeanName(false)) + "()"
715     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFormImplementationGetter()
716     */
717    protected String handleGetFormImplementationGetter()
718    {
719        return "get" + StringUtils.capitalize(this.getFormBeanName(false)) + "()";
720    }
721
722    /**
723     * @return getTarget() instanceof JSFFinalState
724     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#isFinalStateTarget()
725     */
726    protected boolean handleIsFinalStateTarget()
727    {
728        return this.getTarget() instanceof JSFFinalState;
729    }
730
731    /**
732     * @return getName()
733     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getFromOutcome()
734     */
735    protected String handleGetFromOutcome()
736    {
737        return this.getName();
738    }
739
740    /**
741     * @see org.andromda.cartridges.jsf.metafacades.JSFActionLogic#handleIsSuccessMessagesPresent()
742     */
743    protected boolean handleIsSuccessMessagesPresent()
744    {
745        return !this.getSuccessMessages().isEmpty();
746    }
747
748    /**
749     * @see org.andromda.cartridges.jsf.metafacades.JSFActionLogic#handleIsWarningMessagesPresent()
750     */
751    protected boolean handleIsWarningMessagesPresent()
752    {
753        return !this.getWarningMessages().isEmpty();
754    }
755
756    /**
757     * Collects specific messages in a map.
758     *
759     * @param taggedValue the tagged value from which to read the message
760     * @return maps message keys to message values, but only those that match the arguments
761     *         will have been recorded
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>(); // we want to keep the order
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     * @see org.andromda.cartridges.jsf.metafacades.JSFActionLogic#handleGetSuccessMessages()
787     */
788    protected Map<String, String> handleGetSuccessMessages()
789    {
790        return this.getMessages(JSFProfile.TAGGEDVALUE_ACTION_SUCCESS_MESSAGE);
791    }
792
793    /**
794     * @see org.andromda.cartridges.jsf.metafacades.JSFActionLogic#handleGetWarningMessages()
795     */
796    protected Map<String, String> handleGetWarningMessages()
797    {
798        return this.getMessages(JSFProfile.TAGGEDVALUE_ACTION_WARNING_MESSAGE);
799    }
800
801    /**
802     * @return needsFileUpload
803     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#isNeedsFileUpload()
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     * @see org.andromda.cartridges.jsf.metafacades.JSFAction#getTriggerMethodName
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}