Java tutorial
/* * Copyright (C) 2017 FormKiQ Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.formkiq.core.webflow; import static com.formkiq.core.util.CollectionUtil.last; import java.util.ArrayList; import java.util.List; import java.util.Optional; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.lang3.tuple.Pair; import org.springframework.util.StringUtils; import com.formkiq.core.form.tokenizer.TokenType; import com.formkiq.core.form.tokenizer.TokenizerService; import com.formkiq.core.form.tokenizer.TokenizerServiceImpl; import com.formkiq.core.form.tokenizer.TokenizerToken; /** * Class to Manage {@link WebFlow}s. * */ public final class FlowManager { /** Flow Execution Parameter. */ public static final String PARAMETER_EXECUTION = "execution"; /** Session Variable for the max Web flow ID. */ public static final String WEBFLOW_SESSION_ID = "FK_WEBFLOW_ID"; /** * Finish Flow. * @param request {@link HttpServletRequest} */ public static void finish(final HttpServletRequest request) { WebFlow flow = getCurrentWebFlow(request); request.getSession().removeAttribute(getExecutionSessionKey(flow.getSessionKey()).getLeft()); } /** * Gets the current {@link WebFlow} or create a new one. * @param request {@link HttpServletRequest} * @return {@link WebFlow} */ public static WebFlow get(final HttpServletRequest request) { return getCurrentWebFlow(request); } /** * Finds the current {@link WebFlow} if one exists. * @param req {@link HttpServletRequest} * @return {@link WebFlow} */ private static WebFlow getCurrentWebFlow(final HttpServletRequest req) { Pair<String, Integer> webflowkey = getExecutionSessionKey(req.getParameter(PARAMETER_EXECUTION)); String sessionKey = webflowkey.getLeft(); if (StringUtils.hasText(sessionKey)) { Object obj = req.getSession().getAttribute(sessionKey); if (obj instanceof WebFlow) { WebFlow wf = (WebFlow) obj; return wf; } } throw new FlowNotFoundException(); } /** * Get Event Id. * @param request {@link HttpServletRequest} * @return int */ public static int getEventId(final HttpServletRequest request) { Pair<String, Integer> webflowkey = getExecutionSessionKey(request.getParameter(PARAMETER_EXECUTION)); Integer eventId = webflowkey.getRight(); return eventId != null ? eventId.intValue() : 1; } /** * Gets the SessionKey from the Execution Parameter. * @param webflowkey {@link String} * @return {@link Pair} */ public static Pair<String, Integer> getExecutionSessionKey(final String webflowkey) { String s = null; Integer e = null; if (StringUtils.hasText(webflowkey)) { TokenizerService ts = new TokenizerServiceImpl(webflowkey); Optional<TokenizerToken> session = ts.nextToken(); Optional<TokenizerToken> sessionNo = ts.nextToken(); Optional<TokenizerToken> event = ts.nextToken(); Optional<TokenizerToken> eventNo = ts.nextToken(); boolean tokensPresent = session.isPresent() && sessionNo.isPresent() && event.isPresent() && eventNo.isPresent(); if (tokensPresent && session.get().getType().equals(TokenType.STRING) && sessionNo.get().getType().equals(TokenType.INTEGER) && event.get().getType().equals(TokenType.STRING) && eventNo.get().getType().equals(TokenType.INTEGER)) { s = session.get().getValue() + sessionNo.get().getValue(); e = Integer.valueOf(eventNo.get().getValue()); } } return Pair.of(s, e); } /** * Gets the Next WebFlow Session Id. * @param req {@link HttpServletRequest} * @return int */ private static int getNextWebFlowSessionId(final HttpServletRequest req) { int sessionId = 1; HttpSession session = req.getSession(); Object sessionOb = session.getAttribute(WEBFLOW_SESSION_ID); if (sessionOb != null) { try { sessionId = Integer.parseInt(sessionOb.toString()) + 1; } catch (NumberFormatException e) { sessionId = 1; } } session.setAttribute(WEBFLOW_SESSION_ID, String.valueOf(sessionId)); return sessionId; } /** * Start new WebFlow. * @param <T> {@link FlowEventProcessor} * @param request {@link HttpServletRequest} * @param eventProcessor Class * @param states {@link List} * @return {@link WebFlow} */ public static <T extends FlowEventProcessor> WebFlow start(final HttpServletRequest request, final Class<T> eventProcessor, final List<FlowState> states) { if (states.isEmpty()) { throw new IllegalArgumentException("states is empty"); } List<FlowState> newstates = new ArrayList<>(states); if (!FlowStateType.START.equals(newstates.get(0).getType())) { newstates.add(0, new FlowState(FlowStateType.START)); } if (!FlowStateType.START.equals(newstates.get(0).getType())) { newstates.add(0, new FlowState(FlowStateType.START)); } if (!last(newstates).isEnd()) { newstates.add(new FlowState(FlowStateType.END)); } int webflowSessionID = getNextWebFlowSessionId(request); WebFlow flow = new WebFlow(webflowSessionID, eventProcessor, newstates); request.getSession().setAttribute(getExecutionSessionKey(flow.getSessionKey()).getLeft(), flow); return flow; } /** * Transition WebFlow. * @param request {@link HttpServletRequest} * @param transition {@link FlowTransition} * @return {@link WebFlow} */ public static WebFlow transition(final HttpServletRequest request, final FlowTransition transition) { WebFlow flow = getCurrentWebFlow(request); int eventId = flow.getEventId(); if (FlowTransition.BACKWARD.equals(transition)) { flow.setEventId(Math.max(1, eventId - 1)); } else if (FlowTransition.FORWARD.equals(transition)) { flow.setEventId(Math.max(1, eventId + 1)); } return flow; } /** * private constructor. */ private FlowManager() { } }