001package org.andromda.cartridges.bpm4struts.metafacades;
002
003import java.util.ArrayList;
004import java.util.Collection;
005import java.util.Collections;
006import java.util.Iterator;
007import java.util.LinkedHashMap;
008import java.util.LinkedHashSet;
009import java.util.List;
010import java.util.Map;
011import java.util.Set;
012import org.andromda.cartridges.bpm4struts.Bpm4StrutsProfile;
013import org.andromda.metafacades.uml.EventFacade;
014import org.andromda.metafacades.uml.GuardFacade;
015import org.andromda.metafacades.uml.PseudostateFacade;
016import org.andromda.metafacades.uml.StateVertexFacade;
017import org.andromda.utils.StringUtilsHelper;
018import org.apache.commons.lang.StringUtils;
019/**
020 * MetafacadeLogic implementation.
021 *
022 * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForward
023 * @author Bob Fields
024 */
025public class StrutsForwardLogicImpl
026    extends StrutsForwardLogic
027{
028    private static final long serialVersionUID = 34L;
029    /**
030     * @param metaObject
031     * @param context
032     */
033    public StrutsForwardLogicImpl(
034        Object metaObject,
035        String context)
036    {
037        super(metaObject, context);
038    }
039
040    /**
041     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForwardLogic#handleGetGuardName()
042     */
043    protected String handleGetGuardName()
044    {
045        final GuardFacade guard = this.getGuard();
046        return (guard == null) ? null : guard.getName();
047    }
048
049    /**
050     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForwardLogic#handleIsEnteringPage()
051     */
052    protected boolean handleIsEnteringPage()
053    {
054        return this.isEnteringView();
055    }
056
057    /**
058     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForwardLogic#handleGetForwardName()
059     */
060    protected String handleGetForwardName()
061    {
062        return StringUtilsHelper.toResourceMessageKey(this.resolveName());
063    }
064
065    /**
066     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForwardLogic#handleGetForwardPath()
067     */
068    protected String handleGetForwardPath()
069    {
070        String forwardPath = null;
071
072        final StateVertexFacade target = this.getTarget();
073        if (isEnteringPage())
074        {
075            forwardPath = ((StrutsJsp)target).getFullPath() + ".jsp";
076        }
077        else if (isEnteringFinalState())
078        {
079            forwardPath = ((StrutsFinalState)target).getFullPath();
080        }
081
082        return forwardPath;
083    }
084
085    /**
086     * @return lowerCamelCaseName(resolveName())
087     */
088    protected String handleGetActionMethodName()
089    {
090        return StringUtilsHelper.lowerCamelCaseName(this.resolveName());
091    }
092
093    /**
094     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForwardLogic#handleGetTargetNameKey()
095     */
096    protected String handleGetTargetNameKey()
097    {
098        if (this.isEnteringPage())
099        {
100            return ((StrutsJsp)this.getTarget()).getTitleKey();
101        }
102        else if (this.isEnteringFinalState())
103        {
104            return ((StrutsUseCase)((StrutsFinalState)this.getTarget()).getTargetUseCase()).getTitleKey();
105        }
106        return null;
107    }
108
109    /**
110     * If this forward has a trigger this method returns that trigger's name, otherwise if this forward
111     * has a name this method returns that name, otherwise if this forward's target has a name this
112     * method returns that name, otherwise simply returns <code>"unknown"</code>
113     */
114    private String resolveName()
115    {
116        String forwardName = null;
117        //trigger
118        final EventFacade trigger = this.getTrigger();
119        if (trigger != null) forwardName = trigger.getName();
120        //name
121        if (StringUtils.isEmpty(forwardName)) forwardName = this.getName();
122        //target
123        if (StringUtils.isEmpty(forwardName)) forwardName = this.getTarget().getName();
124        // else
125        if (StringUtils.isEmpty(forwardName)) forwardName = "unknown";
126        // return
127        return forwardName;
128    }
129
130    /**
131     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForwardLogic#handleIsExitingPage()
132     */
133    protected boolean handleIsExitingPage()
134    {
135        return this.isExitingView();
136    }
137
138    /**
139     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForwardLogic#handleIsSuccessMessagesPresent()
140     */
141    protected boolean handleIsSuccessMessagesPresent()
142    {
143        return !this.getSuccessMessages().isEmpty();
144    }
145
146    /**
147     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForwardLogic#handleIsWarningMessagesPresent()
148     */
149    protected boolean handleIsWarningMessagesPresent()
150    {
151        return !this.getWarningMessages().isEmpty();
152    }
153
154    /**
155     * Collects specific messages in a map.
156     *
157     * @param taggedValue the tagged value from which to read the message
158     * @return maps message keys to message values, but only those that match the arguments
159     *         will have been recorded
160     */
161    private Map getMessages(String taggedValue)
162    {
163        Map messages;
164
165        final Collection taggedValues = this.findTaggedValues(taggedValue);
166        if (taggedValues.isEmpty())
167        {
168            messages = Collections.emptyMap();
169        }
170        else
171        {
172            messages = new LinkedHashMap(); // we want to keep the order
173
174            for (final Iterator iterator = taggedValues.iterator(); iterator.hasNext();)
175            {
176                final String value = (String)iterator.next();
177                messages.put(StringUtilsHelper.toResourceMessageKey(value), value);
178            }
179        }
180
181        return messages;
182    }
183
184    /**
185     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForwardLogic#handleGetSuccessMessages()
186     */
187    protected Map handleGetSuccessMessages()
188    {
189        return this.getMessages(Bpm4StrutsProfile.TAGGEDVALUE_ACTION_SUCCESS_MESSAGE);
190    }
191
192    /**
193     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForwardLogic#handleGetWarningMessages()
194     */
195    protected Map handleGetWarningMessages()
196    {
197        return this.getMessages(Bpm4StrutsProfile.TAGGEDVALUE_ACTION_WARNING_MESSAGE);
198    }
199
200    /**
201     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsForwardLogic#handleGetStrutsActivityGraph()
202     */
203    protected Object handleGetStrutsActivityGraph()
204    {
205        return this.getFrontEndActivityGraph();
206    }
207
208    /**
209     * Overridden since StrutsAction doesn't extend FrontEndAction.
210     *
211     * @see org.andromda.metafacades.uml.FrontEndForward#getActions()
212     */
213    public List getActions()
214    {
215        final Set actions = new LinkedHashSet();
216        this.findActions(actions, new LinkedHashSet());
217        return new ArrayList(actions);
218    }
219
220    /**
221     * Recursively finds all actions for this forward, what this means depends on the context in which
222     * this forward is used: if the source is a page action state it will collect all actions going out
223     * of this page, if the source is a regular action state it will collect all actions that might traverse
224     * this action state, if the source is the initial state it will collect all actions forwarding to this
225     * forward's use-case (please not that those actions most likely are defined in other use-cases).
226     *
227     * @param actions         the default set of actions, duplicates will not be recorded
228     * @param handledForwards the forwards already processed
229     */
230    private final void findActions(
231        final Set actions,
232        final Set handledForwards)
233    {
234        if (!handledForwards.contains(this))
235        {
236            handledForwards.add(this);
237
238            if (this instanceof StrutsAction) // @todo this is not so nice because StrutsAction extends StrutsForward, solution would be to override in StrutsAction
239            {
240                actions.add(this);
241            }
242            else
243            {
244                final StateVertexFacade vertex = getSource();
245                if (vertex instanceof StrutsJsp)
246                {
247                    final StrutsJsp jsp = (StrutsJsp)vertex;
248                    actions.addAll(jsp.getActions());
249                }
250                else if (vertex instanceof StrutsActionState)
251                {
252                    final StrutsActionState actionState = (StrutsActionState)vertex;
253                    actions.addAll(actionState.getContainerActions());
254                }
255                else if (vertex instanceof PseudostateFacade)
256                {
257                    final PseudostateFacade pseudostate = (PseudostateFacade)vertex;
258                    if (!pseudostate.isInitialState())
259                    {
260                        final Collection incomingForwards = pseudostate.getIncomings();
261                        for (final Iterator forwardIterator = incomingForwards.iterator(); forwardIterator.hasNext();)
262                        {
263                            final StrutsForward forward = (StrutsForward)forwardIterator.next();
264                            actions.addAll(forward.getActions());
265                        }
266                    }
267                }
268            }
269        }
270    }
271}