001package org.andromda.cartridges.bpm4struts.metafacades;
002
003import java.util.ArrayList;
004import java.util.Collection;
005import java.util.Iterator;
006import java.util.LinkedHashSet;
007import java.util.List;
008import java.util.Set;
009import org.andromda.metafacades.uml.FrontEndAction;
010import org.andromda.metafacades.uml.FrontEndUseCase;
011import org.andromda.metafacades.uml.TransitionFacade;
012import org.andromda.metafacades.uml.UMLProfile;
013import org.andromda.metafacades.uml.UseCaseFacade;
014import org.apache.commons.lang.StringUtils;
015
016/**
017 * MetafacadeLogic implementation.
018 *
019 * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsFinalState
020 * @author Bob Fields
021 */
022public class StrutsFinalStateLogicImpl
023    extends StrutsFinalStateLogic
024{
025    private static final long serialVersionUID = 34L;
026    /**
027     * @param metaObject
028     * @param context
029     */
030    public StrutsFinalStateLogicImpl(
031        Object metaObject,
032        String context)
033    {
034        super(metaObject, context);
035    }
036
037    /**
038     * @see org.andromda.metafacades.uml.ModelElementFacade#getName()
039     */
040    public String getName()
041    {
042        String name = super.getName();
043
044        if (name == null)
045        {
046            final UseCaseFacade useCase = this.getTargetUseCase();
047            if (useCase != null)
048            {
049                name = useCase.getName();
050            }
051        }
052
053        return name;
054    }
055
056    /**
057     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsFinalStateLogic#handleGetFullPath()
058     */
059    protected String handleGetFullPath()
060    {
061        String fullPath = null;
062
063        final StrutsUseCase useCase = (StrutsUseCase)this.getTargetUseCase();
064        if (useCase == null)
065        {
066            // perhaps this final state links outside of the UML model
067            final Object taggedValue = this.findTaggedValue(UMLProfile.TAGGEDVALUE_EXTERNAL_HYPERLINK);
068            if (taggedValue == null)
069            {
070                String name = getName();
071                if (StringUtils.isNotBlank(name) && ((name.charAt(0) == '/') || name.startsWith("http://")))
072                {
073                    fullPath = name;
074                }
075            }
076            else
077            {
078                fullPath = String.valueOf(taggedValue);
079            }
080        }
081        else
082        {
083            fullPath = useCase.getActionPath() + ".do";
084        }
085        return fullPath;
086    }
087
088    /**
089     * Overridden for now (//TODO need to figure out why it doesn't work correctly when using
090     * the one from the FrontEndFinalState).
091     *
092     * @see org.andromda.metafacades.uml.FrontEndFinalState#getTargetUseCase()
093     */
094    public FrontEndUseCase getTargetUseCase()
095    {
096        FrontEndUseCase targetUseCase = null;
097        // first check if there is a hyperlink from this final state to a use-case
098        // this works at least in MagicDraw
099        final Object taggedValue = this.findTaggedValue(UMLProfile.TAGGEDVALUE_MODEL_HYPERLINK);
100        if (taggedValue != null)
101        {
102            if (taggedValue instanceof StrutsActivityGraph)
103            {
104                targetUseCase = (FrontEndUseCase)((StrutsActivityGraph)taggedValue).getUseCase();
105            }
106            else if (taggedValue instanceof StrutsUseCase)
107            {
108                targetUseCase = (FrontEndUseCase)taggedValue;
109            }
110        }
111
112        // maybe the name points to a use-case ?
113        if (targetUseCase == null)
114        {
115            final String name = super.getName();
116            if (StringUtils.isNotBlank(name))
117            {
118                UseCaseFacade useCase = getModel().findUseCaseByName(name);
119                if (useCase instanceof FrontEndUseCase)
120                {
121                    targetUseCase = (FrontEndUseCase)useCase;
122                }
123            }
124        }
125        return targetUseCase;
126    }
127
128    /**
129     * Need to override default handling in StateVertexFacade.handleGetActions()
130     * @return handleGetActions()
131     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsFinalStateLogicImpl#handleGetActions()
132     */
133    public List<FrontEndAction> getActions()
134    {
135        return handleGetActions();
136    }
137
138    /**
139     * @return getIncomings().getActions()
140     * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsFinalStateLogicImpl#handleGetActions()
141     */
142    // TODO StateVertexFacade.handleGetActions calls getOutgoings. Why?
143    // Changed from previous handleGetActions because that could never be called by FacadeLogic which delegates to StateVertexFacade.
144    //@Override
145    protected List<FrontEndAction> handleGetActions()
146    {
147        Set<FrontEndAction> actions = new LinkedHashSet<FrontEndAction>();
148        Collection<TransitionFacade> incomings = this.getIncomings();
149
150        for (final Iterator<TransitionFacade> incomingIterator = incomings.iterator(); incomingIterator.hasNext();)
151        {
152            StrutsForward forward = (StrutsForward)incomingIterator.next();
153            actions.addAll(forward.getActions());
154        }
155        return new ArrayList<FrontEndAction>(actions);
156    }
157}