1 25 package org.ofbiz.base.util.template; 26 27 import java.io.File ; 28 import java.io.IOException ; 29 import java.io.InputStreamReader ; 30 import java.io.Reader ; 31 import java.io.StringReader ; 32 import java.io.Writer ; 33 import java.net.MalformedURLException ; 34 import java.net.URL ; 35 import java.util.ArrayList ; 36 import java.util.HashMap ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 import java.util.Locale ; 40 import java.util.Map ; 41 import java.util.Set ; 42 43 import javax.servlet.ServletContext ; 44 import javax.servlet.http.HttpServletRequest ; 45 46 import javolution.util.FastMap; 47 48 import org.ofbiz.base.location.FlexibleLocation; 49 import org.ofbiz.base.util.Debug; 50 import org.ofbiz.base.util.UtilValidate; 51 import org.ofbiz.base.util.cache.UtilCache; 52 53 import freemarker.core.Environment; 54 import freemarker.ext.beans.BeanModel; 55 import freemarker.ext.beans.BeansWrapper; 56 import freemarker.template.Configuration; 57 import freemarker.template.SimpleHash; 58 import freemarker.template.SimpleScalar; 59 import freemarker.template.Template; 60 import freemarker.template.TemplateException; 61 import freemarker.template.TemplateHashModel; 62 import freemarker.template.TemplateModel; 63 import freemarker.template.TemplateModelException; 64 66 67 74 public class FreeMarkerWorker { 75 76 public static final String module = FreeMarkerWorker.class.getName(); 77 78 public static UtilCache cachedTemplates = new UtilCache("template.ftl.general", 0, 0, false); 80 public static UtilCache cachedLocationTemplates = new UtilCache("template.ftl.location", 0, 0, false); 82 83 public static Map ftlTransforms = new HashMap (); 84 85 static { 86 try { 87 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 88 89 ftlTransforms.put("ofbizUrl", loader.loadClass("org.ofbiz.webapp.ftl.OfbizUrlTransform").newInstance()); 92 ftlTransforms.put("ofbizContentUrl", loader.loadClass("org.ofbiz.webapp.ftl.OfbizContentTransform").newInstance()); 93 ftlTransforms.put("ofbizCurrency", loader.loadClass("org.ofbiz.webapp.ftl.OfbizCurrencyTransform").newInstance()); 94 ftlTransforms.put("ofbizAmount", loader.loadClass("org.ofbiz.webapp.ftl.OfbizAmountTransform").newInstance()); 95 ftlTransforms.put("setRequestAttribute", loader.loadClass("org.ofbiz.webapp.ftl.SetRequestAttributeMethod").newInstance()); 96 ftlTransforms.put("renderWrappedText", loader.loadClass("org.ofbiz.webapp.ftl.RenderWrappedTextTransform").newInstance()); 97 98 ftlTransforms.put("barcodeTransform", loader.loadClass("org.ofbiz.webapp.barcode.BarcodeTransform").newInstance()); 99 100 ftlTransforms.put("menuWrap", loader.loadClass("org.ofbiz.widget.menu.MenuWrapTransform").newInstance()); 101 102 ftlTransforms.put("editRenderSubContent", loader.loadClass("org.ofbiz.content.webapp.ftl.EditRenderSubContentTransform").newInstance()); 103 ftlTransforms.put("renderSubContent", loader.loadClass("org.ofbiz.content.webapp.ftl.RenderSubContentTransform").newInstance()); 104 ftlTransforms.put("loopSubContent", loader.loadClass("org.ofbiz.content.webapp.ftl.LoopSubContentTransform").newInstance()); 105 ftlTransforms.put("traverseSubContent", loader.loadClass("org.ofbiz.content.webapp.ftl.TraverseSubContentTransform").newInstance()); 106 107 ftlTransforms.put("checkPermission", loader.loadClass("org.ofbiz.content.webapp.ftl.CheckPermissionTransform").newInstance()); 108 ftlTransforms.put("injectNodeTrailCsv", loader.loadClass("org.ofbiz.content.webapp.ftl.InjectNodeTrailCsvTransform").newInstance()); 109 110 ftlTransforms.put("editRenderSubContentCache", loader.loadClass("org.ofbiz.content.webapp.ftl.EditRenderSubContentCacheTransform").newInstance()); 111 ftlTransforms.put("renderSubContentCache", loader.loadClass("org.ofbiz.content.webapp.ftl.RenderSubContentCacheTransform").newInstance()); 112 ftlTransforms.put("loopSubContentCache", loader.loadClass("org.ofbiz.content.webapp.ftl.LoopSubContentCacheTransform").newInstance()); 113 ftlTransforms.put("traverseSubContentCache", loader.loadClass("org.ofbiz.content.webapp.ftl.TraverseSubContentCacheTransform").newInstance()); 114 ftlTransforms.put("wrapSubContentCache", loader.loadClass("org.ofbiz.content.webapp.ftl.WrapSubContentCacheTransform").newInstance()); 115 ftlTransforms.put("limitedSubContent", loader.loadClass("org.ofbiz.content.webapp.ftl.LimitedSubContentCacheTransform").newInstance()); 116 ftlTransforms.put("renderSubContentAsText", loader.loadClass("org.ofbiz.content.webapp.ftl.RenderSubContentAsText").newInstance()); 117 ftlTransforms.put("renderContentAsText", loader.loadClass("org.ofbiz.content.webapp.ftl.RenderContentAsText").newInstance()); 118 } catch (ClassNotFoundException e) { 119 Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module); 120 } catch (IllegalAccessException e) { 121 Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module); 122 } catch (InstantiationException e) { 123 Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module); 124 } 125 } 126 127 public static void renderTemplateAtLocation(String location, Map context, Writer outWriter) throws MalformedURLException , TemplateException, IOException { 128 Template template = (Template) cachedTemplates.get(location); 129 if (template == null) { 130 synchronized (FreeMarkerWorker.class) { 131 template = (Template) cachedTemplates.get(location); 132 if (template == null) { 133 URL locationUrl = FlexibleLocation.resolveLocation(location); 134 if (locationUrl == null) { 135 throw new IllegalArgumentException ("FreeMarker file not found at location: " + location); 136 } 137 Reader locationReader = new InputStreamReader (locationUrl.openStream()); 138 139 String locationProtocol = locationUrl.getProtocol(); 140 String filename = null; 141 Configuration config = null; 142 if ("file".equals(locationProtocol)) { 143 String locationFile = locationUrl.getFile(); 144 int lastSlash = locationFile.lastIndexOf("/"); 145 String locationDir = locationFile.substring(0, lastSlash); 146 filename = locationFile.substring(lastSlash + 1); 147 if (Debug.verboseOn()) Debug.logVerbose("FreeMarker render: filename=" + filename + ", locationDir=" + locationDir, module); 148 config = makeSingleUseOfbizFtlConfig(locationDir); 150 } else { 151 filename = locationUrl.toExternalForm(); 152 config = makeDefaultOfbizConfig(); 153 } 154 template = new Template(filename, locationReader, config); 155 156 cachedTemplates.put(location, template); 157 158 Locale locale = (Locale ) context.get("locale"); 160 if (locale == null) 161 locale = Locale.getDefault(); 162 template.setSetting("locale", locale.toString()); 163 } 164 } 165 } 166 167 if (context == null) { 168 context = FastMap.newInstance(); 169 } 170 171 addAllOfbizTransforms(context); 173 174 template.process(context, outWriter); 177 } 178 179 public static void renderTemplate(String templateIdString, String template, Map context, Writer outWriter) throws TemplateException, IOException { 180 Reader templateReader = new StringReader (template); 182 renderTemplate(templateIdString, templateReader, context, outWriter); 183 } 184 185 public static void renderTemplate(String templateIdString, Reader templateReader, Map context, Writer outWriter) throws TemplateException, IOException { 186 if (context == null) { 187 context = new HashMap (); 188 } 189 190 Configuration config = makeDefaultOfbizConfig(); 191 Template template = new Template(templateIdString, templateReader, config); 192 193 Locale locale = (Locale ) context.get("locale"); 195 if (locale == null) 196 locale = Locale.getDefault(); 197 template.setSetting("locale", locale.toString()); 198 199 addAllOfbizTransforms(context); 201 202 cachedTemplates.put(templateIdString, template); 203 template.process(context, outWriter); 206 } 207 208 public static Template getTemplateCached(String dataResourceId) { 209 Template t = (Template)cachedTemplates.get("DataResource:" + dataResourceId); 210 return t; 211 } 212 213 public static void renderTemplateCached(Template template, Map context, Writer outWriter) throws TemplateException, IOException { 214 template.process(context, outWriter); 215 } 216 217 public static void addAllOfbizTransforms(Map context) { 218 BeansWrapper wrapper = BeansWrapper.getDefaultInstance(); 219 TemplateHashModel staticModels = wrapper.getStaticModels(); 220 context.put("Static", staticModels); 221 222 context.putAll(ftlTransforms); 223 } 224 225 private static Configuration defaultOfbizConfig = null; 226 public static Configuration makeDefaultOfbizConfig() throws TemplateException, IOException { 227 if (defaultOfbizConfig == null) { 228 synchronized (FreeMarkerWorker.class) { 229 if (defaultOfbizConfig == null) { 230 Configuration config = new Configuration(); 231 config.setObjectWrapper(BeansWrapper.getDefaultInstance()); 232 config.setSetting("datetime_format", "yyyy-MM-dd HH:mm:ss.SSS"); 233 config.setSetting("number_format", "0.##########"); 234 defaultOfbizConfig = config; 235 } 236 } 237 } 238 return defaultOfbizConfig; 239 } 240 241 public static Configuration makeSingleUseOfbizFtlConfig(String locationDir) throws TemplateException, IOException { 242 Configuration config = new Configuration(); 243 config.setObjectWrapper(BeansWrapper.getDefaultInstance()); 244 config.setSetting("datetime_format", "yyyy-MM-dd HH:mm:ss.SSS"); 245 config.setSetting("number_format", "0.##########"); 246 if (locationDir != null) { 247 File locationDirFile = new File (locationDir); 248 if (locationDirFile != null) { 249 if (locationDirFile.isFile()) { 250 254 throw new IllegalArgumentException ("Could not create FTL Configuration object because locationDir is a file: " + locationDir); 255 } 256 if (locationDirFile != null && locationDirFile.isDirectory()) { 257 config.setDirectoryForTemplateLoading(locationDirFile); 258 } 259 } 260 } 261 return config; 262 } 263 264 public static String getArg(Map args, String key, Environment env) { 265 Map templateContext = (Map ) FreeMarkerWorker.getWrappedObject("context", env); 266 return getArg(args, key, templateContext); 267 } 268 269 public static String getArg(Map args, String key, Map templateContext) { 270 Object o = null; 272 String returnVal = null; 273 o = args.get(key); 274 returnVal = (String ) unwrap(o); 275 if (returnVal == null) { 276 try { 277 if (templateContext != null) { 278 returnVal = (String ) templateContext.get(key); 279 } 280 } catch (ClassCastException e2) { 281 } 283 } 284 return returnVal; 285 } 286 287 public static Object getArgObject(Map args, String key, Map templateContext) { 288 Object o = null; 290 Object returnVal = null; 291 o = args.get(key); 292 returnVal = unwrap(o); 293 if (returnVal == null) { 294 try { 295 if (templateContext != null) { 296 returnVal = templateContext.get(key); 297 } 298 } catch (ClassCastException e2) { 299 } 301 } 302 return returnVal; 303 } 304 305 306 311 public static Object getWrappedObject(String varName, Environment env) { 312 Object obj = null; 313 try { 314 obj = env.getVariable(varName); 315 if (obj != null) { 316 if (obj == TemplateModel.NOTHING) { 317 obj = null; 318 } else if (obj instanceof BeanModel) { 319 BeanModel bean = (BeanModel) obj; 320 obj = bean.getWrappedObject(); 321 } else if (obj instanceof SimpleScalar) { 322 obj = obj.toString(); 323 } 324 } 325 } catch (TemplateModelException e) { 326 Debug.logInfo(e.getMessage(), module); 327 } 328 return obj; 329 } 330 331 336 public static BeanModel getBeanModel(String varName, Environment env) { 337 BeanModel bean = null; 338 try { 339 bean = (BeanModel) env.getVariable(varName); 340 } catch (TemplateModelException e) { 341 Debug.logInfo(e.getMessage(), module); 342 } 343 return bean; 344 } 345 346 public static Object get(SimpleHash args, String key) { 347 Object returnObj = null; 348 Object o = null; 349 try { 350 o = args.get(key); 351 } catch(TemplateModelException e) { 352 Debug.logVerbose(e.getMessage(), module); 353 return returnObj; 354 } 355 356 returnObj = unwrap(o); 357 358 if (returnObj == null) { 359 Object ctxObj = null; 360 try { 361 ctxObj = args.get("context"); 362 } catch(TemplateModelException e) { 363 Debug.logInfo(e.getMessage(), module); 364 return returnObj; 365 } 366 Map ctx = null; 367 if (ctxObj instanceof BeanModel) { 368 ctx = (Map )((BeanModel)ctxObj).getWrappedObject(); 369 returnObj = ctx.get(key); 370 } 371 381 } 382 return returnObj; 383 } 384 385 public static Object unwrap(Object o) { 386 Object returnObj = null; 387 388 if (o == TemplateModel.NOTHING) { 389 returnObj = null; 390 } else if (o instanceof SimpleScalar) { 391 returnObj = o.toString(); 392 } else if (o instanceof BeanModel) { 393 returnObj = ((BeanModel)o).getWrappedObject(); 394 } 395 396 return returnObj; 397 } 398 399 public static void checkForLoop(String path, Map ctx) throws IOException { 400 List templateList = (List )ctx.get("templateList"); 401 if (templateList == null) { 402 templateList = new ArrayList (); 403 } else { 404 if (templateList.contains(path)) { 405 throw new IOException (path + " has already been visited."); 406 } 407 } 408 templateList.add(path); 409 ctx.put("templateList", templateList); 410 return; 411 } 412 413 public static Map createEnvironmentMap(Environment env) { 414 Map templateRoot = new HashMap (); 415 Set varNames = null; 416 try { 417 varNames = env.getKnownVariableNames(); 418 } catch (TemplateModelException e1) { 419 Debug.logError(e1, "Error getting FreeMarker variable names, will not put pass current context on to sub-content", module); 420 } 421 if (varNames != null) { 422 Iterator varNameIter = varNames.iterator(); 423 while (varNameIter.hasNext()) { 424 String varName = (String ) varNameIter.next(); 425 templateRoot.put(varName, FreeMarkerWorker.getWrappedObject(varName, env)); 429 } 430 } 431 return templateRoot; 432 } 433 434 public static void saveContextValues(Map context, String [] saveKeyNames, Map saveMap ) { 435 for (int i=0; i<saveKeyNames.length; i++) { 437 String key = (String )saveKeyNames[i]; 438 Object o = context.get(key); 439 if (o instanceof Map ) 440 o = new HashMap ((Map )o); 441 else if (o instanceof List ) 442 o = new ArrayList ((List )o); 443 saveMap.put(key, o); 444 } 445 return ; 446 } 447 448 public static Map saveValues(Map context, String [] saveKeyNames) { 449 Map saveMap = new HashMap (); 450 for (int i=0; i<saveKeyNames.length; i++) { 451 String key = (String )saveKeyNames[i]; 452 Object o = context.get(key); 453 if (o instanceof Map ) 454 o = new HashMap ((Map )o); 455 else if (o instanceof List ) 456 o = new ArrayList ((List )o); 457 saveMap.put(key, o); 458 } 459 return saveMap; 460 } 461 462 463 public static void reloadValues(Map context, Map saveValues, Environment env ) { 464 Set keySet = saveValues.keySet(); 465 Iterator it = keySet.iterator(); 466 while (it.hasNext()) { 467 String key = (String )it.next(); 468 Object o = saveValues.get(key); 469 if (o instanceof Map ) { 470 Map map = new HashMap (); 471 map.putAll((Map )o); 472 context.put(key, map); 473 } else if (o instanceof List ) { 474 List list = new ArrayList (); 475 list.addAll((List )o); 476 context.put(key, list); 477 } else { 478 context.put(key, o); 479 } 480 env.setVariable(key, autoWrap(o, env)); 481 } 482 return; 483 } 484 485 public static void removeValues(Map context, String [] removeKeyNames ) { 486 for (int i=0; i<removeKeyNames.length; i++) { 487 String key = (String )removeKeyNames[i]; 488 context.remove(key); 489 } 490 return; 491 } 492 493 public static void overrideWithArgs(Map ctx, Map args) { 494 Set keySet = args.keySet(); 495 Iterator it = keySet.iterator(); 496 while (it.hasNext()) { 497 String key = (String )it.next(); 498 Object obj = args.get(key); 499 if (obj != null) { 501 if (obj == TemplateModel.NOTHING) { 502 ctx.put(key, null); 503 } else { 504 Object unwrappedObj = unwrap(obj); 505 if (unwrappedObj == null) 506 unwrappedObj = obj; 507 ctx.put(key, unwrappedObj.toString()); 508 } 509 } else { 510 ctx.put(key, null); 511 } 512 } 513 return; 514 } 515 516 public static void convertContext(Map ctx) { 517 Set keySet = ctx.keySet(); 518 Iterator it = keySet.iterator(); 519 while (it.hasNext()) { 520 String key = (String )it.next(); 521 Object obj = ctx.get(key); 522 if (obj != null) { 523 Object unwrappedObj = unwrap(obj); 524 if (unwrappedObj != null) { 525 ctx.put(key, unwrappedObj); 526 } 527 } 528 } 529 return; 530 } 531 532 public static void getSiteParameters(HttpServletRequest request, Map ctx) { 533 if (request == null) { 534 return; 535 } 536 if (ctx == null) { 537 throw new IllegalArgumentException ("Error in getSiteParameters, context/ctx cannot be null"); 538 } 539 ServletContext servletContext = request.getSession().getServletContext(); 540 String rootDir = (String )ctx.get("rootDir"); 541 String webSiteId = (String )ctx.get("webSiteId"); 542 String https = (String )ctx.get("https"); 543 if (UtilValidate.isEmpty(rootDir)) { 544 rootDir = servletContext.getRealPath("/"); 545 ctx.put("rootDir", rootDir); 546 } 547 if (UtilValidate.isEmpty(webSiteId)) { 548 webSiteId = (String ) servletContext.getAttribute("webSiteId"); 549 ctx.put("webSiteId", webSiteId); 550 } 551 if (UtilValidate.isEmpty(https)) { 552 https = (String ) servletContext.getAttribute("https"); 553 ctx.put("https", https); 554 } 555 return; 556 } 557 558 public static TemplateModel autoWrap(Object obj, Environment env) { 559 BeansWrapper wrapper = BeansWrapper.getDefaultInstance(); 560 TemplateModel templateModelObj = null; 561 try { 562 templateModelObj = wrapper.wrap(obj); 563 } catch(TemplateModelException e) { 564 throw new RuntimeException (e.getMessage()); 565 } 566 return templateModelObj; 567 } 568 } 569 | Popular Tags |