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.include()</code> operation on the
034     * specified context relative path, and push the response data (as a String
035     * onto the evaluation stack.</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 retrieved, or omitted to pop a
041     *     computed String value from the top of the evaluation stack.</li>
042     * </ul>
043     *
044     * <p><strong>WARNING</strong> - This implementation requires a Servlet 2.3
045     * based container, because it uses the new response wrapper facilities.</p>
046     *
047     * <p><strong>DESIGN QUESTION - What about binary content?</strong></p>
048     *
049     * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $
050     * @author Craig R. McClanahan
051     */
052    
053    public class IncludeStep23 extends BaseStep {
054    
055    
056        // ----------------------------------------------------------= Constructors
057    
058    
059        /**
060         * Construct a default instance of this Step.
061         */
062        public IncludeStep23() {
063    
064            super();
065    
066        }
067    
068    
069        /**
070         * Construct an instance of this Step with the specified identifier.
071         *
072         * @param id Step identifier
073         */
074        public IncludeStep23(String id) {
075    
076            super();
077            setId(id);
078    
079        }
080    
081    
082        /**
083         * Construct a fully configured instance of this Step.
084         *
085         * @param id Step identifier
086         * @param page Context-relative url
087         */
088        public IncludeStep23(String id, String page) {
089    
090            super();
091            setId(id);
092            setPage(page);
093    
094        }
095    
096    
097        // ------------------------------------------------------------- Properties
098    
099    
100        /**
101         * The context-relative URL (starting with '/') of the resource to be
102         * retrieved.
103         */
104        protected String page = null;
105    
106        public String getPage() {
107            return (this.page);
108        }
109    
110        public void setPage(String page) {
111            this.page = page;
112        }
113    
114    
115        // --------------------------------------------------------- Public Methods
116    
117    
118        /**
119         * Perform the executable actions related to this Step, in the context of
120         * the specified Context.
121         *
122         * @param context The Context that is tracking our execution state
123         *
124         * @exception StepException if a processing error has occurred
125         */
126        public void execute(Context context) throws StepException {
127    
128            // Make sure our executing Context is a WebContext
129            if (!(context instanceof WebContext))
130                throw new StepException("Execution context is not a WebContext",
131                                        this);
132            WebContext webContext = (WebContext) context;
133    
134            // Get the actual resource reference we will be using
135            String resource = page;
136            if (resource == null) {
137                try {
138                    resource = (String) webContext.pop();
139                } catch (EmptyStackException e) {
140                    throw new StepException("Evaluation stack is empty", this);
141                }
142            }
143    
144            // Create a request dispatcher and response wrapper for this resource
145            RequestDispatcher rd =
146                webContext.getServletContext().getRequestDispatcher(resource);
147            if (rd == null)
148                throw new StepException("No request dispatcher for '" +
149                                        resource + "'", this);
150            ServletRequest request = webContext.getServletRequest();
151            ServletResponse response =
152                new IncludeResponse23(webContext.getServletResponse());
153    
154            // Request the included resource
155            String content = null;
156            try {
157                rd.include(request, response);
158                content = ((IncludeResponse23) response).getContent();
159            } catch (IOException e) {
160                throw new StepException("IOException including '" +
161                                        resource + "'", e, this);
162            } catch (ServletException e) {
163                throw new StepException("ServletException including '" +
164                                        resource + "'", e, this);
165            }
166    
167            // Push the resulting String onto the evaluation stack
168            webContext.push(content);
169    
170        }
171    
172    
173        /**
174         * Render a string representation of this Step.
175         */
176        public String toString() {
177    
178            StringBuffer sb = new StringBuffer("<web:include");
179            if (getId() != null) {
180                sb.append(" id=\"");
181                sb.append(getId());
182                sb.append("\"");
183            }
184            sb.append(" page=\"");
185            sb.append(getPage());
186            sb.append("\"/>");
187            return (sb.toString());
188    
189        }
190    
191    
192    }