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 }