1 4 package com.opensymphony.webwork.portlet.velocity; 5 6 import com.opensymphony.webwork.ServletActionContext; 7 import com.opensymphony.webwork.config.Configuration; 8 import com.opensymphony.webwork.util.VelocityWebWorkUtil; 9 import com.opensymphony.webwork.util.WebWorkUtil; 10 import com.opensymphony.webwork.views.jsp.ui.OgnlTool; 11 import com.opensymphony.webwork.views.util.ContextUtil; 12 import com.opensymphony.webwork.views.velocity.BodyTagDirective; 13 import com.opensymphony.webwork.views.velocity.ParamDirective; 14 import com.opensymphony.webwork.views.velocity.TagDirective; 15 import com.opensymphony.webwork.views.velocity.WebWorkVelocityContext; 16 import com.opensymphony.webwork.views.velocity.components.*; 17 import com.opensymphony.xwork.ObjectFactory; 18 import com.opensymphony.xwork.util.OgnlValueStack; 19 import org.apache.commons.logging.Log; 20 import org.apache.commons.logging.LogFactory; 21 import org.apache.velocity.VelocityContext; 22 import org.apache.velocity.app.Velocity; 23 import org.apache.velocity.app.VelocityEngine; 24 import org.apache.velocity.context.Context; 25 import org.apache.velocity.tools.view.ToolboxManager; 26 import org.apache.velocity.tools.view.context.ChainedContext; 27 import org.apache.velocity.tools.view.servlet.ServletToolboxManager; 28 29 import javax.servlet.ServletContext ; 30 import javax.servlet.http.HttpServletRequest ; 31 import javax.servlet.http.HttpServletResponse ; 32 import java.io.File ; 33 import java.io.FileInputStream ; 34 import java.io.IOException ; 35 import java.io.InputStream ; 36 import java.util.*; 37 38 46 47 52 public class VelocityManager { 53 56 private static final Log log = LogFactory.getLog(VelocityManager.class); 57 58 private static VelocityManager instance; 59 60 public static final String ACTION_URL = "actionURL"; 63 64 public static final String ACTION_XURL = "actionXURL"; 65 66 public static final String WEBWORK = "webwork"; 67 68 71 public static final String PARENT = "parent"; 72 73 76 public static final String TAG = "tag"; 77 78 private OgnlTool ognlTool = OgnlTool.getInstance(); 81 82 private VelocityEngine velocityEngine; 83 84 87 protected ToolboxManager toolboxManager = null; 88 89 private String toolBoxLocation; 90 91 private VelocityContext[] chainedContexts; 92 93 96 private String [] chainedContextNames; 97 98 101 protected VelocityManager() { 102 init(); 103 } 104 105 108 111 public synchronized static VelocityManager getInstance() { 112 if (instance == null) { 113 String classname = VelocityManager.class.getName(); 114 115 if (Configuration.isSet("webwork.velocity.manager.classname")) { 116 classname = Configuration.getString("webwork.velocity.manager.classname").trim(); 117 } 118 119 if (!classname.equals(VelocityManager.class.getName())) { 120 try { 121 log.info("Instantiating VelocityManager!, " + classname); 122 instance = (VelocityManager) ObjectFactory.getObjectFactory().buildBean(Class.forName(classname)); 123 } catch (Exception e) { 124 log.fatal("Fatal exception occurred while trying to instantiate a VelocityManager instance, " + classname, e); 125 instance = new VelocityManager(); 126 } 127 } else { 128 instance = new VelocityManager(); 129 } 130 } 131 132 return instance; 133 } 134 135 140 public VelocityEngine getVelocityEngine() { 141 return velocityEngine; 142 } 143 144 159 public Context createContext(OgnlValueStack stack, HttpServletRequest req, HttpServletResponse res) { 160 VelocityContext[] chainedContexts = prepareChainedContexts(req, res); 162 WebWorkVelocityContext context = new WebWorkVelocityContext(chainedContexts, stack); 163 164 Map standardMap = ContextUtil.getStandardContext(stack, req, res); 165 for (Iterator iterator = standardMap.entrySet().iterator(); iterator.hasNext();) { 166 Map.Entry entry = (Map.Entry) iterator.next(); 167 context.put((String ) entry.getKey(), entry.getValue()); 168 } 169 context.put(WEBWORK, new VelocityWebWorkUtil(context, stack, req, res)); 170 171 175 String actionURL = com.opensymphony.webwork.portlet.context.PortletContext.getContext().getActionURL(); 176 String actionXURL = actionURL + "?wwXAction="; 177 context.put(ACTION_URL, actionURL); 178 context.put(ACTION_XURL, actionXURL); 179 181 ServletContext ctx = null; 182 try { 183 ctx = ServletActionContext.getServletContext(); 184 } catch (NullPointerException npe) { 185 log.debug("internal toolbox context ignored"); 187 } 188 189 if (toolboxManager != null && ctx != null) { 190 ChainedContext chained = new ChainedContext(context, req, res, ctx); 191 chained.setToolbox(toolboxManager.getToolboxContext(null)); 192 return chained; 193 } else { 194 return context; 195 } 196 197 } 198 199 208 protected VelocityContext[] prepareChainedContexts(HttpServletRequest servletRequest, HttpServletResponse servletResponse) { 209 if (this.chainedContextNames == null) { 210 return null; 211 } 212 List contextList = new ArrayList(); 213 for (int i = 0; i < chainedContextNames.length; i++) { 214 String className = chainedContextNames[i]; 215 try { 216 VelocityContext velocityContext = (VelocityContext) ObjectFactory.getObjectFactory().buildBean(className); 217 contextList.add(velocityContext); 218 } catch (Exception e) { 219 log.warn("Warning. " + e.getClass().getName() + " caught while attempting to instantiate a chained VelocityContext, " 220 + className + " -- skipping"); 221 } 222 } 223 if (contextList.size() > 0) { 224 VelocityContext[] extraContexts = new VelocityContext[contextList.size()]; 225 contextList.toArray(extraContexts); 226 return extraContexts; 227 } else { 228 return null; 229 } 230 } 231 232 239 public synchronized void init(ServletContext context) { 240 if (velocityEngine == null) { 241 velocityEngine = newVelocityEngine(context); 242 } 243 this.initToolbox(context); 244 } 245 246 258 public Properties loadConfiguration(ServletContext context) { 259 if (context == null) { 260 String gripe = "Error attempting to create a loadConfiguration from a null ServletContext!"; 261 log.error(gripe); 262 throw new IllegalArgumentException (gripe); 263 } 264 265 Properties properties = new Properties(); 266 267 applyDefaultConfiguration(context, properties); 269 270 String defaultUserDirective = properties.getProperty("userdirective"); 272 273 280 String configfile; 281 282 if (Configuration.isSet("webwork.velocity.configfile")) { 283 configfile = Configuration.getString("webwork.velocity.configfile"); 284 } else { 285 configfile = "velocity.properties"; 286 } 287 288 configfile = configfile.trim(); 289 290 InputStream in = null; 291 String resourceLocation = null; 292 293 try { 294 if (context.getRealPath(configfile) != null) { 295 String filename = context.getRealPath(configfile); 297 298 if (filename != null) { 299 File file = new File (filename); 300 301 if (file.isFile()) { 302 resourceLocation = file.getCanonicalPath() + " from file system"; 303 in = new FileInputStream (file); 304 } 305 306 if (in == null) { 309 file = new File (context.getRealPath("/WEB-INF/" + configfile)); 310 311 if (file.isFile()) { 312 resourceLocation = file.getCanonicalPath() + " from file system"; 313 in = new FileInputStream (file); 314 } 315 } 316 } 317 } 318 319 if (in == null) { 322 in = VelocityManager.class.getClassLoader().getResourceAsStream(configfile); 323 if (in != null) { 324 resourceLocation = configfile + " from classloader"; 325 } 326 } 327 328 if (in != null) { 330 log.info("Initializing velocity using " + resourceLocation); 331 properties.load(in); 332 } 333 } catch (IOException e) { 334 log.warn("Unable to load velocity configuration " + resourceLocation, e); 335 } finally { 336 if (in != null) { 337 try { 338 in.close(); 339 } catch (IOException e) { 340 } 341 } 342 } 343 344 String userdirective = properties.getProperty("userdirective"); 346 347 if ((userdirective == null) || userdirective.trim().equals("")) { 348 userdirective = defaultUserDirective; 349 } else { 350 userdirective = userdirective.trim() + "," + defaultUserDirective; 351 } 352 353 properties.setProperty("userdirective", userdirective); 354 356 if (log.isDebugEnabled()) { 359 log.debug("Initializing Velocity with the following properties ..."); 360 361 for (Iterator iter = properties.keySet().iterator(); iter.hasNext();) { 362 String key = (String ) iter.next(); 363 String value = properties.getProperty(key); 364 365 if (log.isDebugEnabled()) { 366 log.warn(" '" + key + "' = '" + value + "'"); 367 } 368 } 369 } 370 371 return properties; 372 } 373 374 377 protected void init() { 378 379 initChainedContexts(); 381 382 if (Configuration.isSet("webwork.velocity.toolboxlocation")) { 383 toolBoxLocation = Configuration.get("webwork.velocity.toolboxlocation").toString(); 384 } 385 386 } 387 388 394 protected void initToolbox(ServletContext context) { 395 396 if (toolBoxLocation != null) { 397 toolboxManager = ServletToolboxManager.getInstance(context, toolBoxLocation); 398 } else { 399 Velocity.info("VelocityViewServlet: No toolbox entry in configuration."); 400 } 401 } 402 403 411 protected void initChainedContexts() { 412 413 if (Configuration.isSet("webwork.velocity.contexts")) { 414 String contexts = Configuration.get("webwork.velocity.contexts").toString(); 416 StringTokenizer st = new StringTokenizer(contexts, ","); 417 List contextList = new ArrayList(); 418 419 while (st.hasMoreTokens()) { 420 String classname = st.nextToken(); 421 contextList.add(classname); 422 } 423 if (contextList.size() > 0) { 424 String [] chainedContexts = new String [contextList.size()]; 425 contextList.toArray(chainedContexts); 426 this.chainedContextNames = chainedContexts; 427 } 428 429 } 430 431 } 432 433 462 protected VelocityEngine newVelocityEngine(ServletContext context) { 463 if (context == null) { 464 String gripe = "Error attempting to create a new VelocityEngine from a null ServletContext!"; 465 log.error(gripe); 466 throw new IllegalArgumentException (gripe); 467 } 468 469 Properties p = loadConfiguration(context); 470 471 VelocityEngine velocityEngine = new VelocityEngine(); 472 473 try { 474 velocityEngine.init(p); 475 } catch (Exception e) { 476 String gripe = "Unable to instantiate VelocityEngine!"; 477 log.error(gripe, e); 478 throw new RuntimeException (gripe); 479 } 480 481 return velocityEngine; 482 } 483 484 498 private void applyDefaultConfiguration(ServletContext context, Properties p) { 499 501 505 if (p.getProperty(Velocity.RESOURCE_LOADER) == null) { 506 p.setProperty(Velocity.RESOURCE_LOADER, "wwfile, wwclass"); 507 } 508 509 515 if (context.getRealPath("") != null) { 516 p.setProperty("wwfile.resource.loader.description", "Velocity File Resource Loader"); 517 p.setProperty("wwfile.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader"); 518 p.setProperty("wwfile.resource.loader.path", context.getRealPath("")); 519 p.setProperty("wwfile.resource.loader.modificationCheckInterval", "2"); 520 p.setProperty("wwfile.resource.loader.cache", "true"); 521 } else { 522 String prop = p.getProperty(Velocity.RESOURCE_LOADER); 524 if (prop.indexOf("wwfile,") != -1) { 525 prop = replace(prop, "wwfile,", ""); 526 } else if (prop.indexOf(", wwfile") != -1) { 527 prop = replace(prop, ", wwfile", ""); 528 } else if (prop.indexOf("wwfile") != -1) { 529 prop = replace(prop, "wwfile", ""); 530 } 531 532 p.setProperty(Velocity.RESOURCE_LOADER, prop); 533 } 534 535 542 p.setProperty("wwclass.resource.loader.description", "Velocity Classpath Resource Loader"); 543 p.setProperty("wwclass.resource.loader.class", "com.opensymphony.webwork.views.velocity.WebWorkResourceLoader"); 544 p.setProperty("wwclass.resource.loader.modificationCheckInterval", "2"); 545 p.setProperty("wwclass.resource.loader.cache", "true"); 546 547 StringBuffer sb = new StringBuffer (); 549 550 addDirective(sb, BodyTagDirective.class); 552 addDirective(sb, TagDirective.class); 553 addDirective(sb, ParamDirective.class); 554 555 addDirective(sb, ApplyDecoratorDirective.class); 556 addDirective(sb, CheckBoxDirective.class); 557 addDirective(sb, CheckBoxListDirective.class); 558 addDirective(sb, ComboBoxDirective.class); 559 addDirective(sb, ComponentDirective.class); 560 addDirective(sb, DatePickerDirective.class); 561 addDirective(sb, DivDirective.class); 562 addDirective(sb, DoubleSelectDirective.class); 563 addDirective(sb, FileDirective.class); 564 addDirective(sb, FormDirective.class); 565 addDirective(sb, HiddenDirective.class); 566 addDirective(sb, HrefDirective.class); 567 addDirective(sb, LabelDirective.class); 568 addDirective(sb, PanelDirective.class); 569 addDirective(sb, PasswordDirective.class); 570 addDirective(sb, RadioDirective.class); 571 addDirective(sb, SelectDirective.class); 572 addDirective(sb, SubmitDirective.class); 573 addDirective(sb, TabbedPanelDirective.class); 574 addDirective(sb, TextAreaDirective.class); 575 addDirective(sb, TextFieldDirective.class); 576 addDirective(sb, TokenDirective.class); 577 578 String directives = sb.toString(); 579 580 String userdirective = p.getProperty("userdirective"); 581 if ((userdirective == null) || userdirective.trim().equals("")) { 582 userdirective = directives; 583 } else { 584 userdirective = userdirective.trim() + "," + directives; 585 } 586 587 p.setProperty("userdirective", userdirective); 588 } 589 590 private void addDirective(StringBuffer sb, Class clazz) { 591 sb.append(clazz.getName()).append(","); 592 } 593 594 private static final String replace(String string, String oldString, String newString) { 595 if (string == null) { 596 return null; 597 } 598 if (newString == null) { 601 return string; 602 } 603 int i = 0; 604 if ((i = string.indexOf(oldString, i)) >= 0) { 607 char[] string2 = string.toCharArray(); 609 char[] newString2 = newString.toCharArray(); 610 int oLength = oldString.length(); 611 StringBuffer buf = new StringBuffer (string2.length); 612 buf.append(string2, 0, i).append(newString2); 613 i += oLength; 614 int j = i; 615 while ((i = string.indexOf(oldString, i)) > 0) { 617 buf.append(string2, j, i - j).append(newString2); 618 i += oLength; 619 j = i; 620 } 621 buf.append(string2, j, string2.length - j); 622 return buf.toString(); 623 } 624 return string; 625 } 626 } | Popular Tags |