001    /*
002     * Copyright 1999-2001,2004 The Apache Software Foundation.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */ 
016    
017    package org.apache.commons.workflow.web;
018    
019    
020    import java.io.IOException;
021    import java.util.EmptyStackException;
022    import javax.servlet.RequestDispatcher;
023    import javax.servlet.ServletException;
024    import javax.servlet.ServletRequest;
025    import javax.servlet.ServletResponse;
026    import org.apache.commons.workflow.Context;
027    import org.apache.commons.workflow.StepException;
028    import org.apache.commons.workflow.base.BaseStep;
029    import org.apache.commons.workflow.util.WorkflowUtils;
030    
031    
032    /**
033     * <p>Perform a <code>RequestDispatcher.forward()</code> operation on the
034     * specified context relative path, and tell our <code>Context</code> to
035     * suspend execution until control is returned.</p>
036     *
037     * <p>Supported Attributes:</p>
038     * <ul>
039     * <li><strong>page</strong> - Context relative URL (starting with a slash)
040     *     of the application resource to be forwarded to, or omitted to pop a
041     *     computed String value from the top of the evaluation stack.</li>
042     * </ul>
043     *
044     * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $
045     * @author Craig R. McClanahan
046     */
047    
048    public class ForwardStep extends BaseStep {
049    
050    
051        // ----------------------------------------------------------= Constructors
052    
053    
054        /**
055         * Construct a default instance of this Step.
056         */
057        public ForwardStep() {
058    
059            super();
060    
061        }
062    
063    
064        /**
065         * Construct an instance of this Step with the specified identifier.
066         *
067         * @param id Step identifier
068         */
069        public ForwardStep(String id) {
070    
071            super();
072            setId(id);
073    
074        }
075    
076    
077        /**
078         * Construct a fully configured instance of this Step.
079         *
080         * @param id Step identifier
081         * @param page Context-relative url
082         */
083        public ForwardStep(String id, String page) {
084    
085            super();
086            setId(id);
087            setPage(page);
088    
089        }
090    
091    
092        // ------------------------------------------------------------- Properties
093    
094    
095        /**
096         * The context-relative URL (starting with '/') of the resource to be
097         * forwarded to.
098         */
099        protected String page = null;
100    
101        public String getPage() {
102            return (this.page);
103        }
104    
105        public void setPage(String page) {
106            this.page = page;
107        }
108    
109    
110        // --------------------------------------------------------- Public Methods
111    
112    
113        /**
114         * Perform the executable actions related to this Step, in the context of
115         * the specified Context.
116         *
117         * @param context The Context that is tracking our execution state
118         *
119         * @exception StepException if a processing error has occurred
120         */
121        public void execute(Context context) throws StepException {
122    
123            // Make sure our executing Context is a WebContext
124            if (!(context instanceof WebContext))
125                throw new StepException("Execution context is not a WebContext",
126                                        this);
127            WebContext webContext = (WebContext) context;
128    
129            // Get the actual resource reference we will be using
130            String resource = page;
131            if (resource == null) {
132                try {
133                    resource = (String) webContext.pop();
134                } catch (EmptyStackException e) {
135                    throw new StepException("Evaluation stack is empty", this);
136                }
137            }
138    
139            // Create a request dispatcher for this resource
140            RequestDispatcher rd =
141                webContext.getServletContext().getRequestDispatcher(resource);
142            if (rd == null)
143                throw new StepException("No request dispatcher for '" +
144                                        resource + "'", this);
145            ServletRequest request = webContext.getServletRequest();
146            ServletResponse response = webContext.getServletResponse();
147    
148            // Forward to the requested resource
149            try {
150                rd.forward(request, response);
151            } catch (IOException e) {
152                throw new StepException("IOException forwarding to '" +
153                                        resource + "'", e, this);
154            } catch (ServletException e) {
155                throw new StepException("ServletException forwarding to '" +
156                                        resource + "'", e, this);
157            }
158    
159            // Signal our Context to suspend execution
160            context.setSuspend(true);
161    
162        }
163    
164    
165        /**
166         * Render a string representation of this Step.
167         */
168        public String toString() {
169    
170            StringBuffer sb = new StringBuffer("<web:forward");
171            if (getId() != null) {
172                sb.append(" id=\"");
173                sb.append(getId());
174                sb.append("\"");
175            }
176            sb.append(" page=\"");
177            sb.append(getPage());
178            sb.append("\"/>");
179            return (sb.toString());
180    
181        }
182    
183    
184    }