/* * Copyright (c) 2001-2015, Inversoft Inc., All Rights Reserved * * 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 org.primeframework.mvc.action; import javax.servlet.ServletException; import java.io.IOException; import org.primeframework.mvc.PrimeException; import org.primeframework.mvc.action.result.ResultStore; import org.primeframework.mvc.util.ReflectionUtils; import org.primeframework.mvc.workflow.WorkflowChain; import com.google.inject.Inject; /** * This class is the default implementation of the action invocation workflow. It looks up the ActionInvocation using * the ActionMappingWorkflow and the invokes the action using reflection. * * @author Brian Pontarelli */ public class DefaultActionInvocationWorkflow implements ActionInvocationWorkflow { private final ActionInvocationStore actionInvocationStore; private final ResultStore resultStore; @Inject public DefaultActionInvocationWorkflow(ActionInvocationStore actionInvocationStore, ResultStore resultStore) { this.resultStore = resultStore; this.actionInvocationStore = actionInvocationStore; } /** * Performs the action invocation using this process. * <p> * <h3>Action-less request</h3> * <p> * <ul> <li>Continue down the chain</li> </ul> * <p> * <h3>Action request</h3> * <p> * <ul> <li>Invoke the action</li> </ul> * * @param chain The chain. * @throws IOException If the chain throws an IOException. * @throws ServletException If the chain throws a ServletException or if the result can't be found. */ @SuppressWarnings("unchecked") public void perform(WorkflowChain chain) throws IOException, ServletException { ActionInvocation actionInvocation = actionInvocationStore.getCurrent(); if (actionInvocation.action != null) { String resultCode = execute(actionInvocation); resultStore.set(resultCode); } chain.continueWorkflow(); } /** * Invokes the execute method on the action. This first checks if there is an extension and if there is it looks for * a * method with the same name. Next, it looks for a method that matches the current method (i.e. get or post) and * finally falls back to execute. * * @param actionInvocation The action invocation. * @return The result code from the execute method and never null. * @throws ServletException If the execute method doesn't exist, has the wrong signature, couldn't be invoked, threw * an exception or returned null. */ protected String execute(ActionInvocation actionInvocation) throws ServletException { Object action = actionInvocation.action; String result = ReflectionUtils.invoke(actionInvocation.method.method, action); if (result == null) { throw new PrimeException("The action class [" + action.getClass() + "] returned " + "null for the result code. Execute methods must never return null."); } return result; } }