001// Generated by delombok at Sun Jul 30 17:21:56 UTC 2023
002package de.cuioss.test.jsf.mocks;
003
004import static de.cuioss.tools.collect.CollectionLiterals.mutableList;
005import static java.util.Objects.requireNonNull;
006import java.io.IOException;
007import java.util.Arrays;
008import java.util.HashMap;
009import java.util.HashSet;
010import java.util.List;
011import java.util.Map;
012import java.util.Set;
013import javax.faces.application.ConfigurableNavigationHandler;
014import javax.faces.application.NavigationCase;
015import javax.faces.context.FacesContext;
016import org.apache.myfaces.test.mock.MockExternalContext;
017import de.cuioss.tools.logging.CuiLogger;
018import de.cuioss.tools.string.Joiner;
019
020/**
021 * Simulate {@link ConfigurableNavigationHandler}
022 */
023public class CuiMockConfigurableNavigationHandler extends ConfigurableNavigationHandler {
024    private static final CuiLogger log = new CuiLogger(CuiMockConfigurableNavigationHandler.class);
025    private final Map<String, Set<NavigationCase>> navigationCases = new HashMap<>();
026    private boolean getNavigationCaseCalled = false;
027    private boolean handleNavigationCalled = false;
028    private boolean addNavigationCalled = false;
029    private boolean addNavigationWithFromActionCalled = false;
030    private String calledOutcome;
031
032    @Override
033    public NavigationCase getNavigationCase(final FacesContext context, final String fromAction, final String outcome) {
034        // Api Check
035        requireNonNull(context, "FacesContext must not be null");
036        getNavigationCaseCalled = true;
037        return getFirstFittingNavigationCase(fromAction, outcome);
038    }
039
040    @Override
041    public void handleNavigation(final FacesContext context, final String fromAction, final String outcome) {
042        if (!(context.getExternalContext() instanceof MockExternalContext)) {
043            throw new UnsupportedOperationException("handleNavigation is working only with MockExternalContext");
044        }
045        final var navigationCase = getNavigationCase(context, fromAction, outcome);
046        final var externalContext = (MockExternalContext) context.getExternalContext();
047        var newViewId = outcome;
048        try {
049            if (null == navigationCase) {
050                externalContext.redirect(outcome);
051            } else {
052                newViewId = navigationCase.getToViewId(context);
053                externalContext.redirect(newViewId);
054            }
055        } catch (IOException e) {
056            throw new IllegalStateException(e);
057        }
058        context.getViewRoot().setViewId(newViewId);
059        calledOutcome = outcome;
060        handleNavigationCalled = true;
061    }
062
063    /**
064     * Add NavigationCase for outcome
065     *
066     * @param outcome
067     * @param navigationCase
068     * @return the create {@link NavigationCase}
069     */
070    public CuiMockConfigurableNavigationHandler addNavigationCase(final String outcome, final NavigationCase navigationCase) {
071        this.addNavigationCase(null, outcome, navigationCase);
072        addNavigationCalled = true;
073        return this;
074    }
075
076    /**
077     * Add NavigationCase for attributes fromAction and outcome
078     *
079     * @param fromAction     String
080     * @param outcome        String
081     * @param navigationCase {@link NavigationCase}
082     * @return fluent api style
083     */
084    public CuiMockConfigurableNavigationHandler addNavigationCase(final String fromAction, final String outcome, final NavigationCase navigationCase) {
085        final var key = calculateKey(fromAction, outcome);
086        navigationCases.remove(key);
087        navigationCases.put(key, new HashSet<>(Arrays.asList(navigationCase)));
088        addNavigationWithFromActionCalled = true;
089        return this;
090    }
091
092    private NavigationCase getFirstFittingNavigationCase(final String fromAction, final String outcome) {
093        final var key = calculateKey(fromAction, outcome);
094        if (navigationCases.containsKey(key)) {
095            final List<NavigationCase> list = mutableList(navigationCases.get(key));
096            return list.get(0);
097        }
098        log.warn("Could not find requested navigation case \'{}\'." + " You can programmatically register the navigation case using ApplicationConfigDecorator#registerNavigationCase.", key);
099        return null;
100    }
101
102    private static String calculateKey(final String fromAction, final String outcome) {
103        return Joiner.on("|").skipNulls().join(fromAction, outcome);
104    }
105
106    @java.lang.SuppressWarnings("all")
107    @lombok.Generated
108    public Map<String, Set<NavigationCase>> getNavigationCases() {
109        return this.navigationCases;
110    }
111
112    @java.lang.SuppressWarnings("all")
113    @lombok.Generated
114    public boolean isGetNavigationCaseCalled() {
115        return this.getNavigationCaseCalled;
116    }
117
118    @java.lang.SuppressWarnings("all")
119    @lombok.Generated
120    public boolean isHandleNavigationCalled() {
121        return this.handleNavigationCalled;
122    }
123
124    @java.lang.SuppressWarnings("all")
125    @lombok.Generated
126    public boolean isAddNavigationCalled() {
127        return this.addNavigationCalled;
128    }
129
130    @java.lang.SuppressWarnings("all")
131    @lombok.Generated
132    public boolean isAddNavigationWithFromActionCalled() {
133        return this.addNavigationWithFromActionCalled;
134    }
135
136    @java.lang.SuppressWarnings("all")
137    @lombok.Generated
138    public String getCalledOutcome() {
139        return this.calledOutcome;
140    }
141}