1 5 package com.opensymphony.webwork.views.velocity; 6 7 import com.opensymphony.webwork.ServletActionContext; 8 import com.opensymphony.webwork.config.Configuration; 9 import com.opensymphony.webwork.portlet.velocity.ApplyDecoratorDirective; 10 import com.opensymphony.webwork.util.VelocityWebWorkUtil; 11 import com.opensymphony.webwork.views.jsp.ui.OgnlTool; 12 import com.opensymphony.webwork.views.util.ContextUtil; 13 import com.opensymphony.webwork.views.velocity.components.*; 14 import com.opensymphony.xwork.ObjectFactory; 15 import com.opensymphony.xwork.util.OgnlValueStack; 16 import org.apache.commons.logging.Log; 17 import org.apache.commons.logging.LogFactory; 18 import org.apache.velocity.VelocityContext; 19 import org.apache.velocity.app.Velocity; 20 import org.apache.velocity.app.VelocityEngine; 21 import org.apache.velocity.context.Context; 22 import org.apache.velocity.tools.view.ToolboxManager; 23 import org.apache.velocity.tools.view.context.ChainedContext; 24 import org.apache.velocity.tools.view.servlet.ServletToolboxManager; 25 26 import javax.servlet.ServletContext ; 27 import javax.servlet.http.HttpServletRequest ; 28 import javax.servlet.http.HttpServletResponse ; 29 import java.io.File ; 30 import java.io.FileInputStream ; 31 import java.io.IOException ; 32 import java.io.InputStream ; 33 import java.util.*; 34 35 36 41 public class VelocityManager { 42 44 private static final Log log = LogFactory.getLog(VelocityManager.class); 45 private static VelocityManager instance; 46 public static final String WEBWORK = "webwork"; 47 48 51 public static final String PARENT = "parent"; 52 53 56 public static final String TAG = "tag"; 57 58 60 private OgnlTool ognlTool = OgnlTool.getInstance(); 61 private VelocityEngine velocityEngine; 62 63 66 protected ToolboxManager toolboxManager = null; 67 private String toolBoxLocation; 68 69 70 73 private String [] chainedContextNames; 74 75 77 protected VelocityManager() { 78 init(); 79 } 80 81 83 86 public synchronized static VelocityManager getInstance() { 87 if (instance == null) { 88 String classname = VelocityManager.class.getName(); 89 90 if (Configuration.isSet("webwork.velocity.manager.classname")) { 91 classname = Configuration.getString("webwork.velocity.manager.classname").trim(); 92 } 93 94 if (!classname.equals(VelocityManager.class.getName())) { 95 try { 96 log.info("Instantiating VelocityManager!, " + classname); 97 instance = (VelocityManager) ObjectFactory.getObjectFactory().buildBean(Class.forName(classname)); 98 } catch (Exception e) { 99 log.fatal("Fatal exception occurred while trying to instantiate a VelocityManager instance, " + classname, e); 100 instance = new VelocityManager(); 101 } 102 } else { 103 instance = new VelocityManager(); 104 } 105 } 106 107 return instance; 108 } 109 110 114 public VelocityEngine getVelocityEngine() { 115 return velocityEngine; 116 } 117 118 133 public Context createContext(OgnlValueStack stack, HttpServletRequest req, HttpServletResponse res) { 134 VelocityContext[] chainedContexts = prepareChainedContexts(req, res); 135 WebWorkVelocityContext context = new WebWorkVelocityContext(chainedContexts, stack); 136 Map standardMap = ContextUtil.getStandardContext(stack, req, res); 137 for (Iterator iterator = standardMap.entrySet().iterator(); iterator.hasNext();) { 138 Map.Entry entry = (Map.Entry) iterator.next(); 139 context.put((String ) entry.getKey(), entry.getValue()); 140 } 141 context.put(WEBWORK, new VelocityWebWorkUtil(context, stack, req, res)); 142 143 144 ServletContext ctx = null; 145 try { 146 ctx = ServletActionContext.getServletContext(); 147 } catch (NullPointerException npe) { 148 log.debug("internal toolbox context ignored"); 150 } 151 152 if (toolboxManager != null && ctx != null) { 153 ChainedContext chained = new ChainedContext(context, req, res, ctx); 154 chained.setToolbox(toolboxManager.getToolboxContext(null)); 155 return chained; 156 } else { 157 return context; 158 } 159 160 } 161 162 171 protected VelocityContext[] prepareChainedContexts(HttpServletRequest servletRequest, HttpServletResponse servletResponse) { 172 if (this.chainedContextNames == null) { 173 return null; 174 } 175 List contextList = new ArrayList(); 176 for (int i = 0; i < chainedContextNames.length; i++) { 177 String className = chainedContextNames[i]; 178 try { 179 VelocityContext velocityContext = (VelocityContext) ObjectFactory.getObjectFactory().buildBean(className); 180 contextList.add(velocityContext); 181 } catch (Exception e) { 182 log.warn("Warning. " + e.getClass().getName() + " caught while attempting to instantiate a chained VelocityContext, " + className + " -- skipping"); 183 } 184 } 185 if (contextList.size() > 0) { 186 VelocityContext[] extraContexts = new VelocityContext[contextList.size()]; 187 contextList.toArray(extraContexts); 188 return extraContexts; 189 } else { 190 return null; 191 } 192 } 193 194 200 public synchronized void init(ServletContext context) { 201 if (velocityEngine == null) { 202 velocityEngine = newVelocityEngine(context); 203 } 204 this.initToolbox(context); 205 } 206 207 218 public Properties loadConfiguration(ServletContext context) { 219 if (context == null) { 220 String gripe = "Error attempting to create a loadConfiguration from a null ServletContext!"; 221 log.error(gripe); 222 throw new IllegalArgumentException (gripe); 223 } 224 225 Properties properties = new Properties(); 226 227 applyDefaultConfiguration(context, properties); 229 230 String defaultUserDirective = properties.getProperty("userdirective"); 231 232 240 String configfile; 241 242 if (Configuration.isSet("webwork.velocity.configfile")) { 243 configfile = Configuration.getString("webwork.velocity.configfile"); 244 } else { 245 configfile = "velocity.properties"; 246 } 247 248 configfile = configfile.trim(); 249 250 InputStream in = null; 251 String resourceLocation = null; 252 253 try { 254 if (context.getRealPath(configfile) != null) { 255 String filename = context.getRealPath(configfile); 257 258 if (filename != null) { 259 File file = new File (filename); 260 261 if (file.isFile()) { 262 resourceLocation = file.getCanonicalPath() + " from file system"; 263 in = new FileInputStream (file); 264 } 265 266 if (in == null) { 268 file = new File (context.getRealPath("/WEB-INF/" + configfile)); 269 270 if (file.isFile()) { 271 resourceLocation = file.getCanonicalPath() + " from file system"; 272 in = new FileInputStream (file); 273 } 274 } 275 } 276 } 277 278 if (in == null) { 280 in = VelocityManager.class.getClassLoader().getResourceAsStream(configfile); 281 if (in != null) { 282 resourceLocation = configfile + " from classloader"; 283 } 284 } 285 286 if (in != null) { 288 log.info("Initializing velocity using " + resourceLocation); 289 properties.load(in); 290 } 291 } catch (IOException e) { 292 log.warn("Unable to load velocity configuration " + resourceLocation, e); 293 } finally { 294 if (in != null) { 295 try { 296 in.close(); 297 } catch (IOException e) { 298 } 299 } 300 } 301 302 String userdirective = properties.getProperty("userdirective"); 303 304 if ((userdirective == null) || userdirective.trim().equals("")) { 305 userdirective = defaultUserDirective; 306 } else { 307 userdirective = userdirective.trim() + "," + defaultUserDirective; 308 } 309 310 properties.setProperty("userdirective", userdirective); 311 312 if (log.isDebugEnabled()) { 314 log.debug("Initializing Velocity with the following properties ..."); 315 316 for (Iterator iter = properties.keySet().iterator(); 317 iter.hasNext();) { 318 String key = (String ) iter.next(); 319 String value = properties.getProperty(key); 320 321 if (log.isDebugEnabled()) { 322 log.debug(" '" + key + "' = '" + value + "'"); 323 } 324 } 325 } 326 327 return properties; 328 } 329 330 333 protected void init() { 334 335 initChainedContexts(); 337 338 339 if (Configuration.isSet("webwork.velocity.toolboxlocation")) { 340 toolBoxLocation = Configuration.get("webwork.velocity.toolboxlocation").toString(); 341 } 342 343 } 344 345 346 350 protected void initToolbox(ServletContext context) { 351 352 if (toolBoxLocation != null) { 353 toolboxManager = ServletToolboxManager.getInstance(context, toolBoxLocation); 354 } else { 355 Velocity.info("VelocityViewServlet: No toolbox entry in configuration."); 356 } 357 } 358 359 360 366 protected void initChainedContexts() { 367 368 if (Configuration.isSet("webwork.velocity.contexts")) { 369 String contexts = Configuration.get("webwork.velocity.contexts").toString(); 371 StringTokenizer st = new StringTokenizer(contexts, ","); 372 List contextList = new ArrayList(); 373 374 while (st.hasMoreTokens()) { 375 String classname = st.nextToken(); 376 contextList.add(classname); 377 } 378 if (contextList.size() > 0) { 379 String [] chainedContexts = new String [contextList.size()]; 380 contextList.toArray(chainedContexts); 381 this.chainedContextNames = chainedContexts; 382 } 383 384 385 } 386 387 } 388 389 414 protected VelocityEngine newVelocityEngine(ServletContext context) { 415 if (context == null) { 416 String gripe = "Error attempting to create a new VelocityEngine from a null ServletContext!"; 417 log.error(gripe); 418 throw new IllegalArgumentException (gripe); 419 } 420 421 Properties p = loadConfiguration(context); 422 423 VelocityEngine velocityEngine = new VelocityEngine(); 424 425 try { 426 velocityEngine.init(p); 427 } catch (Exception e) { 428 String gripe = "Unable to instantiate VelocityEngine!"; 429 log.error(gripe, e); 430 throw new RuntimeException (gripe); 431 } 432 433 return velocityEngine; 434 } 435 436 447 private void applyDefaultConfiguration(ServletContext context, Properties p) { 448 450 454 if (p.getProperty(Velocity.RESOURCE_LOADER) == null) { 455 p.setProperty(Velocity.RESOURCE_LOADER, "wwfile, wwclass"); 456 } 457 458 464 if (context.getRealPath("") != null) { 465 p.setProperty("wwfile.resource.loader.description", "Velocity File Resource Loader"); 466 p.setProperty("wwfile.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader"); 467 p.setProperty("wwfile.resource.loader.path", context.getRealPath("")); 468 p.setProperty("wwfile.resource.loader.modificationCheckInterval", "2"); 469 p.setProperty("wwfile.resource.loader.cache", "true"); 470 } else { 471 String prop = p.getProperty(Velocity.RESOURCE_LOADER); 473 if (prop.indexOf("wwfile,") != -1) { 474 prop = replace(prop, "wwfile,", ""); 475 } else if (prop.indexOf(", wwfile") != -1) { 476 prop = replace(prop, ", wwfile", ""); 477 } else if (prop.indexOf("wwfile") != -1) { 478 prop = replace(prop, "wwfile", ""); 479 } 480 481 p.setProperty(Velocity.RESOURCE_LOADER, prop); 482 } 483 484 490 p.setProperty("wwclass.resource.loader.description", "Velocity Classpath Resource Loader"); 491 p.setProperty("wwclass.resource.loader.class", "com.opensymphony.webwork.views.velocity.WebWorkResourceLoader"); 492 p.setProperty("wwclass.resource.loader.modificationCheckInterval", "2"); 493 p.setProperty("wwclass.resource.loader.cache", "true"); 494 495 StringBuffer sb = new StringBuffer (); 497 498 addDirective(sb, BodyTagDirective.class); 500 addDirective(sb, TagDirective.class); 501 addDirective(sb, ParamDirective.class); 502 503 addDirective(sb, ApplyDecoratorDirective.class); 504 505 addDirective(sb, ActionDirective.class); 506 addDirective(sb, CheckBoxDirective.class); 507 addDirective(sb, CheckBoxListDirective.class); 508 addDirective(sb, ComboBoxDirective.class); 509 addDirective(sb, ComponentDirective.class); 510 addDirective(sb, DatePickerDirective.class); 511 addDirective(sb, DivDirective.class); 512 addDirective(sb, DoubleSelectDirective.class); 513 addDirective(sb, FileDirective.class); 514 addDirective(sb, FormDirective.class); 515 addDirective(sb, HiddenDirective.class); 516 addDirective(sb, IncludeDirective.class); 517 addDirective(sb, HrefDirective.class); 518 addDirective(sb, LabelDirective.class); 519 addDirective(sb, PanelDirective.class); 520 addDirective(sb, PasswordDirective.class); 521 addDirective(sb, RadioDirective.class); 522 addDirective(sb, SelectDirective.class); 523 addDirective(sb, SubmitDirective.class); 524 addDirective(sb, TabbedPanelDirective.class); 525 addDirective(sb, TextAreaDirective.class); 526 addDirective(sb, TextFieldDirective.class); 527 addDirective(sb, TokenDirective.class); 528 addDirective(sb, URLDirective.class); 529 530 String directives = sb.toString(); 531 532 String userdirective = p.getProperty("userdirective"); 533 if ((userdirective == null) || userdirective.trim().equals("")) { 534 userdirective = directives; 535 } else { 536 userdirective = userdirective.trim() + "," + directives; 537 } 538 539 p.setProperty("userdirective", userdirective); 540 } 541 542 private void addDirective(StringBuffer sb, Class clazz) { 543 sb.append(clazz.getName()).append(","); 544 } 545 546 private static final String replace(String string, String oldString, String newString) { 547 if (string == null) { 548 return null; 549 } 550 if (newString == null) { 552 return string; 553 } 554 int i = 0; 555 if ((i = string.indexOf(oldString, i)) >= 0) { 557 char[] string2 = string.toCharArray(); 559 char[] newString2 = newString.toCharArray(); 560 int oLength = oldString.length(); 561 StringBuffer buf = new StringBuffer (string2.length); 562 buf.append(string2, 0, i).append(newString2); 563 i += oLength; 564 int j = i; 565 while ((i = string.indexOf(oldString, i)) > 0) { 567 buf.append(string2, j, i - j).append(newString2); 568 i += oLength; 569 j = i; 570 } 571 buf.append(string2, j, string2.length - j); 572 return buf.toString(); 573 } 574 return string; 575 } 576 } 577 | Popular Tags |