1 52 53 package freemarker.ext.jsp; 54 55 import java.io.IOException ; 56 import java.util.ArrayList ; 57 import java.util.Collections ; 58 import java.util.Enumeration ; 59 import java.util.List ; 60 61 import javax.servlet.GenericServlet ; 62 import javax.servlet.Servlet ; 63 import javax.servlet.ServletConfig ; 64 import javax.servlet.ServletContext ; 65 import javax.servlet.ServletException ; 66 import javax.servlet.ServletRequest ; 67 import javax.servlet.ServletResponse ; 68 import javax.servlet.http.HttpServletRequest ; 69 import javax.servlet.http.HttpServletResponse ; 70 import javax.servlet.http.HttpSession ; 71 import javax.servlet.jsp.JspWriter ; 72 import javax.servlet.jsp.PageContext ; 73 import javax.servlet.jsp.tagext.Tag ; 74 75 import freemarker.core.Environment; 76 import freemarker.ext.servlet.FreemarkerServlet; 77 import freemarker.ext.servlet.HttpRequestHashModel; 78 import freemarker.ext.servlet.ServletContextHashModel; 79 import freemarker.ext.util.WrapperTemplateModel; 80 import freemarker.template.ObjectWrapper; 81 import freemarker.template.TemplateBooleanModel; 82 import freemarker.template.TemplateHashModelEx; 83 import freemarker.template.TemplateModel; 84 import freemarker.template.TemplateModelException; 85 import freemarker.template.TemplateModelIterator; 86 import freemarker.template.TemplateNumberModel; 87 import freemarker.template.TemplateScalarModel; 88 import freemarker.template.utility.UndeclaredThrowableException; 89 90 94 class FreeMarkerPageContext extends PageContext implements TemplateModel 95 { 96 private static final String NO_FM_SERVLET = 97 "FreeMarker JSP taglib integration can not be used outside the " + 98 "FreemarkerServlet environment."; 99 100 private final Environment environment; 101 private List tags = new ArrayList (); 102 private List outs = new ArrayList (); 103 private final GenericServlet servlet; 104 private HttpSession session; 105 private final HttpServletRequest request; 106 private final HttpServletResponse response; 107 private final ObjectWrapper wrapper; 108 private JspWriter jspOut; 109 110 static FreeMarkerPageContext getCurrentPageContext() throws TemplateModelException { 111 Environment env = Environment.getCurrentEnvironment(); 112 TemplateModel pageContextModel = env.getGlobalVariable(PAGECONTEXT); 113 if(pageContextModel instanceof FreeMarkerPageContext) { 114 return (FreeMarkerPageContext)pageContextModel; 115 } 116 FreeMarkerPageContext pageContext = new FreeMarkerPageContext(); 117 env.setGlobalVariable(PAGECONTEXT, pageContext); 118 return pageContext; 119 } 120 121 private FreeMarkerPageContext() 122 throws 123 TemplateModelException 124 { 125 environment = Environment.getCurrentEnvironment(); 126 127 TemplateModel appModel = 128 environment.getGlobalVariable(FreemarkerServlet.KEY_APPLICATION); 129 if(appModel instanceof ServletContextHashModel) { 130 this.servlet = ((ServletContextHashModel)appModel).getServlet(); 131 } 132 else { 133 throw new 134 TemplateModelException( 135 "Could not find the Application data model." + 136 NO_FM_SERVLET); 137 } 138 139 TemplateModel requestModel = 140 environment.getGlobalVariable(FreemarkerServlet.KEY_REQUEST); 141 if(requestModel instanceof HttpRequestHashModel) { 142 HttpRequestHashModel reqHash = (HttpRequestHashModel)requestModel; 143 this.request = reqHash.getRequest(); 144 this.session = request.getSession(false); 145 this.response = reqHash.getResponse(); 146 this.wrapper = reqHash.getObjectWrapper(); 147 } 148 else { 149 throw new 150 TemplateModelException( 151 "Could not find the Request data model." + 152 NO_FM_SERVLET); 153 } 154 155 setAttribute(REQUEST, request); 157 setAttribute(RESPONSE, response); 158 if (session != null) 159 setAttribute(SESSION, session); 160 setAttribute(PAGE, servlet); 161 setAttribute(CONFIG, servlet.getServletConfig()); 162 setAttribute(PAGECONTEXT, this); 163 setAttribute(APPLICATION, servlet.getServletContext()); 164 } 165 166 ObjectWrapper getObjectWrapper() { 167 return wrapper; 168 } 169 170 public void initialize( 171 Servlet servlet, ServletRequest request, ServletResponse response, 172 String errorPageURL, boolean needsSession, int bufferSize, 173 boolean autoFlush) 174 { 175 throw new UnsupportedOperationException (); 176 } 177 178 public void release() { 179 } 180 181 public void setAttribute(String name, Object value) { 182 setAttribute(name, value, PAGE_SCOPE); 183 } 184 185 public void setAttribute(String name, Object value, int scope) { 186 switch(scope) { 187 case PAGE_SCOPE: { 188 try { 189 environment.setGlobalVariable(name, wrapper.wrap(value)); 190 break; 191 } 192 catch(TemplateModelException e) { 193 throw new UndeclaredThrowableException(e); 194 } 195 } 196 case REQUEST_SCOPE: { 197 getRequest().setAttribute(name, value); 198 break; 199 } 200 case SESSION_SCOPE: { 201 getSession(true).setAttribute(name, value); 202 break; 203 } 204 case APPLICATION_SCOPE: { 205 getServletContext().setAttribute(name, value); 206 break; 207 } 208 default: { 209 throw new IllegalArgumentException ("Invalid scope " + scope); 210 } 211 } 212 } 213 214 public Object getAttribute(String name) 215 { 216 return getAttribute(name, PAGE_SCOPE); 217 } 218 219 public Object getAttribute(String name, int scope) 220 { 221 switch (scope) { 222 case PAGE_SCOPE: { 223 try { 224 TemplateModel m = environment.getGlobalNamespace().get(name); 225 if (m instanceof WrapperTemplateModel) { 226 return ((WrapperTemplateModel) m).getWrappedObject(); 227 } else if (m instanceof TemplateScalarModel) { 228 return ((TemplateScalarModel) m).getAsString(); 229 } else if (m instanceof TemplateNumberModel) { 230 return ((TemplateNumberModel) m).getAsNumber(); 231 } else if (m instanceof TemplateBooleanModel) { 232 return ((TemplateBooleanModel) m).getAsBoolean() ? Boolean.TRUE : Boolean.FALSE; 233 } else { 234 return m; 235 } 236 } 237 catch (TemplateModelException e) { 238 throw new UndeclaredThrowableException(e); 239 } 240 } 241 case REQUEST_SCOPE: { 242 return getRequest().getAttribute(name); 243 } 244 case SESSION_SCOPE: { 245 HttpSession session = getSession(false); 246 if(session == null) { 247 return null; 248 } 249 return session.getAttribute(name); 250 } 251 case APPLICATION_SCOPE: { 252 return getServletContext().getAttribute(name); 253 } 254 default: { 255 throw new IllegalArgumentException ("Invalid scope " + scope); 256 } 257 } 258 } 259 260 public Object findAttribute(String name) 261 { 262 Object retval = getAttribute(name, PAGE_SCOPE); 263 if(retval != null) return retval; 264 retval = getAttribute(name, REQUEST_SCOPE); 265 if(retval != null) return retval; 266 retval = getAttribute(name, SESSION_SCOPE); 267 if(retval != null) return retval; 268 return getAttribute(name, APPLICATION_SCOPE); 269 } 270 271 public void removeAttribute(String name) { 272 removeAttribute(name, PAGE_SCOPE); 273 removeAttribute(name, REQUEST_SCOPE); 274 removeAttribute(name, SESSION_SCOPE); 275 removeAttribute(name, APPLICATION_SCOPE); 276 } 277 278 public void removeAttribute(String name, int scope) { 279 switch(scope) { 280 case PAGE_SCOPE: { 281 environment.getGlobalNamespace().remove(name); 282 break; 283 } 284 case REQUEST_SCOPE: { 285 getRequest().removeAttribute(name); 286 break; 287 } 288 case SESSION_SCOPE: { 289 HttpSession session = getSession(false); 290 if(session != null) { 291 session.removeAttribute(name); 292 } 293 break; 294 } 295 case APPLICATION_SCOPE: { 296 getServletContext().removeAttribute(name); 297 break; 298 } 299 default: { 300 throw new IllegalArgumentException ("Invalid scope: " + scope); 301 } 302 } 303 } 304 305 public int getAttributesScope(String name) { 306 if(getAttribute(name, PAGE_SCOPE) != null) return PAGE_SCOPE; 307 if(getAttribute(name, REQUEST_SCOPE) != null) return REQUEST_SCOPE; 308 if(getAttribute(name, SESSION_SCOPE) != null) return SESSION_SCOPE; 309 if(getAttribute(name, APPLICATION_SCOPE) != null) return APPLICATION_SCOPE; 310 return 0; 311 } 312 313 public Enumeration getAttributeNamesInScope(int scope) { 314 switch(scope) { 315 case PAGE_SCOPE: { 316 try { 317 return 318 new TemplateHashModelExEnumeration(environment.getGlobalNamespace()); 319 } 320 catch(TemplateModelException e) { 321 throw new UndeclaredThrowableException(e); 322 } 323 } 324 case REQUEST_SCOPE: { 325 return getRequest().getAttributeNames(); 326 } 327 case SESSION_SCOPE: { 328 HttpSession session = getSession(false); 329 if(session != null) { 330 return session.getAttributeNames(); 331 } 332 return Collections.enumeration(Collections.EMPTY_SET); 333 } 334 case APPLICATION_SCOPE: { 335 return getServletContext().getAttributeNames(); 336 } 337 default: { 338 throw new IllegalArgumentException ("Invalid scope " + scope); 339 } 340 } 341 } 342 343 public JspWriter getOut() { 344 return jspOut; 345 } 346 347 private HttpSession getSession(boolean create) { 348 if(session == null) { 349 session = request.getSession(create); 350 if(session != null) { 351 setAttribute(SESSION, session); 352 } 353 } 354 return session; 355 } 356 357 public HttpSession getSession() { 358 return getSession(false); 359 } 360 361 public Object getPage() { 362 return servlet; 363 } 364 365 public ServletRequest getRequest() { 366 return request; 367 } 368 369 public ServletResponse getResponse() { 370 return response; 371 } 372 373 public Exception getException() { 374 throw new UnsupportedOperationException (); 375 } 376 377 public ServletConfig getServletConfig() { 378 return servlet.getServletConfig(); 379 } 380 381 public ServletContext getServletContext() { 382 return servlet.getServletContext(); 383 } 384 385 public void forward(String url) throws ServletException , IOException { 386 request.getRequestDispatcher(url).forward(request, response); 388 } 389 390 public void include(String url) throws ServletException , IOException { 391 request.getRequestDispatcher(url).include(request, response); 393 } 394 395 public void handlePageException(Exception e) { 396 throw new UnsupportedOperationException (); 397 } 398 399 public void handlePageException(Throwable e) { 400 throw new UnsupportedOperationException (); 401 } 402 403 Tag peekTopTag() { 404 return tags.isEmpty() ? null : (Tag ) tags.get(tags.size() - 1); 405 } 406 407 void popTopTag() { 408 tags.remove(tags.size() - 1); 409 } 410 411 void popWriter() { 412 jspOut = (JspWriter )outs.remove(outs.size() - 1); 413 setAttribute(OUT, jspOut); 414 } 415 416 void pushTopTag(Tag tag) { 417 tags.add(tag); 418 } 419 420 void pushWriter(JspWriter out) { 421 outs.add(jspOut); 422 jspOut = out; 423 setAttribute(OUT, jspOut); 424 } 425 426 private static class TemplateHashModelExEnumeration implements Enumeration { 427 private final TemplateModelIterator it; 428 429 private TemplateHashModelExEnumeration(TemplateHashModelEx hashEx) throws TemplateModelException { 430 it = hashEx.keys().iterator(); 431 } 432 433 public boolean hasMoreElements() { 434 try { 435 return it.hasNext(); 436 } catch (TemplateModelException tme) { 437 throw new UndeclaredThrowableException(tme); 438 } 439 } 440 441 public Object nextElement() { 442 try { 443 return ((TemplateScalarModel) it.next()).getAsString(); 444 } catch (TemplateModelException tme) { 445 throw new UndeclaredThrowableException(tme); 446 } 447 } 448 } 449 } 450 | Popular Tags |