Re: Create an empty java.util.Set in VTL
You can probably use a hack with classloader. Along the lines of: #set($x = "1".getClass().getClassloader().findClass("java.uti.HashSet").newInstance()) Alex On Thu, Jan 25, 2018 at 11:30 AM, Christopher Schultz < ch...@christopherschultz.net> wrote: > -BEGIN PGP SIGNED MESSAGE- > Hash: SHA256 > > All, > > If I want to create a new empty array/collection, I can do something > like this: > > #set($array = []) > > If I want to create a new Map, I can do this: > > #set($map = {}) > > Is there a way to create a new Set? > > I'd like to use a set because: > > 1. I want to use this object as a sort of scratch-area to know what > work I've done before > > and > > 2. I'm going to be consulting it a lot using Set.contains(object) so > something other than ArrayList/LinkedList will be much faster > > Thanks, > - -chris > -BEGIN PGP SIGNATURE- > Comment: GPGTools - http://gpgtools.org > Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ > > iQJRBAEBCAA7FiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAlpqBjsdHGNocmlzQGNo > cmlzdG9waGVyc2NodWx0ei5uZXQACgkQHPApP6U8pFisIQ//VqqfK6GzyxnQZ9qK > QvQREhkJoafg5X7n4d1M7pfG99qGTlGhrLXwO8YD0Qhpj0v7QKbJbi3LsjmwIVQT > 4wvMXO7cBLXbB3bdc640ITylettTqKODTPk/KBIKq4nvSUVMGKvn/q/NlrZFX776 > 11SBC2VLcU7ujzaglL+F/xlF0C1ZS1UAFQlBVcRxT48C44dGOGSYVOu9UmYPvxpk > 4ExrjKwkuTb6zsXn/Nwn1d/K7jB+Cqx77KDNOj0eBQK5POHZa/cC/W0z9uVdlUJg > oVOwxITiEyTd2XmEFa1OjnU4yrZkU+N+wPzsFxgNwKzWSTC4CsBjIw2oSh4cOEqy > gU7HRlCQMRhhBAYD6M7a8wvI60/UI/klb7aB1wOwt74A2/jtwx3M2mBKoYFYTx3X > sfXS1lRtiXLtmooe50wHBvHBhvWXHkLE0dRETtgsLH/QiFgpG3xjoLPHkm6nL/60 > 4KJ5kt/a8afm1dBgcSc4Y6eXrAr0XQl9vREPfGWbcQs3h+azJ2L1leoEg2jnA3gh > oytTF7HmuoX4cYqF1SLeLlMlRJdaAzayZYRwWeB739t7W7iRBzackNzTZyWfNqVD > FRTv3vmsl477J9KI05rH7qlmowFL0QmwP6WeRPtOpQq8gDFKhRcGcoPXRtT6aXke > VGfV9fj4L7nJBBUkOWtSfQU7WuY= > =61WB > -END PGP SIGNATURE- > > - > To unsubscribe, e-mail: user-unsubscr...@velocity.apache.org > For additional commands, e-mail: user-h...@velocity.apache.org > >
Re: strict mode but ignore null
I am guessing that you can also install a reference insert handler in your setup and handle null values there as needed. Alex On Thu, Dec 7, 2017 at 9:35 AM, Claude Brissonwrote: > I looked at the code, and, well, it looks like the strict mode is ... > rather strict. Even quiet references will throw an exception if you try to > access a property on a null object. > > The only thing you can do to circumvent the exception is wrapping the > property use in #if() statements : > > #if($nullobj) $nullobj.someProp #end > > > Claude > > > > On 06/12/2017 23:26, Veit Guna wrote: > >> Hi. >> >> I would like to setup Velocity so that invalid (=unknown) >> properties/methods are throwing an exception, but null values shouldn't. >> And that per default. >> I know that I could use quiet references, but I would have to think >> about everytime, whether it could be null or not. Or use it all the time, >> which I would like to avoid - since I'm lazy :). >> >> I activated strict mode which fails on unknown properties/methods - >> which is good. >> >> But it also fails on something like >> >> $valid.nullPropertyToObject.validproperty >> >> What I would like is, that it doesn't fail because of >> nullPropertyToObject being null. >> >> My basic idea around this is, to spot real errors like unknown >> properties during tests. >> I don't really care about actual null values/references - these should >> be rendered empty in case of null during runtime. >> >> In my tests I assert, that the rendering basically works (all >> properties/methods exist) and values are properly filled. >> But I don't want (ever) to fail only because one property is null during >> runtime. >> >> Is this somehow possible? >> >> I just upgraded to 2.0 hoping that this is handled more flexible now. >> >> Cheers >> Veit >> >> >> >> >> >> - >> To unsubscribe, e-mail: user-unsubscr...@velocity.apache.org >> For additional commands, e-mail: user-h...@velocity.apache.org >> >> >> > > - > To unsubscribe, e-mail: user-unsubscr...@velocity.apache.org > For additional commands, e-mail: user-h...@velocity.apache.org > >
Re: What does Velocimacro with a Body mean?
It does not work because bodyContent is an instance of the ASTNode class and not a string, so it does not have the trim method. Use something like this: #macro(my_trim)#set($str=$bodyContent)$str.trim()#end Test: before#@my_trim()-blah- #{end}after Renders: before-blah-after On Wed, Aug 7, 2013 at 5:09 PM, O. Olson olson_...@yahoo.it wrote: Thank you very much Nathan for clarifying what body content meant. At least now I know what it means, but I think I am having a problem with my trim function here. It seems to delete everything. I have no clue how this worked previously. To avoid naming conflicts, I decided to rename my macro. It now looks like: #macro(query_url $query_param) q=$query_param #end #macro(my_trim)$!bodyContent.trim()#end I call it using #@my_trim()#query_url(sometext)#end And the result is blank i.e. I do not see anything in the result. I now attempt: #macro(my_trim)PREPEND$!bodyContent.trim()#end This time I see only: PREPEND This is expected, but why nothing from $!bodyContent.trim() I don't know what is happening to trim() function i.e. why it is not working. But thank you for answering my question. O. O. - Messaggio originale - Da: Nathan Bubna nbu...@gmail.com A: Velocity Users List user@velocity.apache.org; O. Olson olson_...@yahoo.it Cc: Inviato: Lunedì 5 Agosto 2013 22:34 Oggetto: Re: What does Velocimacro with a Body mean? Yes, all velocimacros have bodies in their definition: #macro( foo ) definition only #end #macro( bar ) definition accepts $bodyContent #end Not all velocimacros accept bodies in their usage: #foo() #@bar() body content when used #end Produces: definition only definition accepts body content when used As to why your example ends up with preceding spaces, i am not certain. The format part in particular, because Velocity has only input text and output text, no format. Try defining your #@trim like so: #macro( trim )$!bodyContent.trim()#end to ensure there are no sneaky whitespaces hiding in the definition. On Mon, Aug 5, 2013 at 9:25 AM, O. Olson olson_...@yahoo.it wrote: Hi, I am new to Velocity and I am wondering what Velocimacro with a Body means? Here, I am referring to the description in http://velocity.apache.org/engine/releases/velocity-1.7/vtl-reference-guide.html#amacro_-_Allows_users_to_define_a_Velocimacro_VM_a_repeated_segment_of_a_VTL_template_as_required I thought all Velocimacros had bodies, just like all non-trivial functions in C or Java have bodies. I attempted the use the above suggestion given in the URL and it did not work. I attempted the following in my Global Library: #macro(query_url $query_param) q=$query_param #end #macro(trim) $!bodyContent.trim() #end According to the above URL, in my template, I called this using: #@trim()#query_url(sometext)#end The result seems to be: q=sometext i.e. there are spaces in the front that I don't like. (Depending on the format you are looking at, these preceeding spaces might be deleted, but they appear in the rendered results.) Any ideas what I am doing wrong? Thank you in advance, O. O. - To unsubscribe, e-mail: user-unsubscr...@velocity.apache.org For additional commands, e-mail: user-h...@velocity.apache.org - To unsubscribe, e-mail: user-unsubscr...@velocity.apache.org For additional commands, e-mail: user-h...@velocity.apache.org - To unsubscribe, e-mail: user-unsubscr...@velocity.apache.org For additional commands, e-mail: user-h...@velocity.apache.org
Re: Returning String without Whitespace from Velocimacros
Simple way: #set($str=#default_query_url()) $str.trim() Can probably create a helper macro trim that does the same thing to the body content: #@trim() #default_query_url() #end On Thu, Aug 1, 2013 at 1:27 PM, O. Olson olson_...@yahoo.it wrote: Hi, I am new to using Apache Velocity. What is the correct way of returning a string from a Macro or a Velocimacro? Since I did not have a clue on how to return a string from a Macro, I decided to do something like #macro(query_url $query_param) q=$query_param #end I can then call the Macro using: #query_url(*) The problem with this is that the resulting value contains a Tab or number of Spaces before the 'q=' when I call it. One option is to delete the spaces like: #macro(query_url $query_param) q=$query_param #end This fixes my problem but is very hard to read. To take this a step further consider: #macro(default_query_url) #if($request.params.get('q')) #query_url($request.params.get('q')) #else #query_url(*) #end #end Vs. #macro(default_query_url) #if($request.params.get('q')) #query_url($request.params.get('q')) #else #query_url(*) #end In the first case there is no whitespace, but editing it would be very difficult for more complicated macros. I am curious what is the correct way to return values from Velocimacros and if I can Trim the resulting Whitespace before returning it? Thank you an advance for any help. O. O. - To unsubscribe, e-mail: user-unsubscr...@velocity.apache.org For additional commands, e-mail: user-h...@velocity.apache.org
Re: Macro caching and other caching
It's not really a Velocity specific suggestion - I would just dump the heap and trace the instances to the garbage collection roots. Eclipse MAT or YourKit can do it as probably can a lot of other Java tools. On Tue, Jul 31, 2012 at 11:37 AM, Bradley Wagner bradley.wag...@hannonhill.com wrote: Whoops, was misreading the API. It's actually that tempTemplateName variable. On Tue, Jul 31, 2012 at 11:21 AM, Bradley Wagner bradley.wag...@hannonhill.com wrote: A StringWriter: String template = ... the string containing the dynamic template to generate ... // Get a template as stream. StringWriter writer = new StringWriter(); StringReader reader = new StringReader(template); // create a temporary template name String tempTemplateName = velocityTransform- + System.currentTimeMillis(); // ask Velocity to evaluate it. VelocityEngine engine = getEngine(); boolean success = engine.evaluate(context, writer, tempTemplateName, reader); if (!success) { LOG.debug(Velocity could not evaluate template with content: \n + template); return null; } LOG.debug(Velocity successfully evaluted template with content: \n + template); String strResult = writer.getBuffer().toString(); return strResult; On Tue, Jul 31, 2012 at 11:10 AM, Nathan Bubna nbu...@gmail.com wrote: What do you use for logTag (template name) when you are using evaluate()? On Tue, Jul 31, 2012 at 8:01 AM, Bradley Wagner bradley.wag...@hannonhill.com wrote: Doing both. In the other case we're using a classpath resource loader to evaluate templates like this: VelocityContext = ... a context that we're building each time ... VelocityEngine engine = ... our single engine ... Template template = engine.getTemplate(templatePath); StringWriter writer = new StringWriter(); template.merge(context, writer); However, we only have 7 of those static templates in our whole system. On Tue, Jul 31, 2012 at 10:52 AM, Nathan Bubna nbu...@gmail.com wrote: And you're sure you're only using VelocityEngine.evaluate? Not loading templates through the resource loader? Or are you doing both? On Mon, Jul 30, 2012 at 2:51 PM, Bradley Wagner bradley.wag...@hannonhill.com wrote: Nathan, Tokens are referenced by org.apache.velocity.runtime.parser.node.ASTReference which seem to be referenced by arrays of org.apache.velocity.runtime.parser.node.Nodes. Most of the classes referencing these things are AST classes in the org.apache.velocity.runtime.parser.node package. Here's our properties file: runtime.log.logsystem.class = org.apache.velocity.runtime.log.Log4JLogChute,org.apache.velocity.runtime.log.AvalonLogSystem runtime.log.logsystem.log4j.logger=com.hannonhill.cascade.velocity.VelocityEngine runtime.log.error.stacktrace = false runtime.log.warn.stacktrace = false runtime.log.info.stacktrace = false runtime.log.invalid.reference = true input.encoding=UTF-8 output.encoding=UTF-8 directive.foreach.counter.name = velocityCount directive.foreach.counter.initial.value = 1 resource.loader = class class.resource.loader.description = Velocity Classpath Resource Loader class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader velocimacro.permissions.allow.inline.local.scope = true Thanks! Bradley On Mon, Jul 30, 2012 at 4:47 PM, Nathan Bubna nbu...@gmail.com wrote: On Mon, Jul 30, 2012 at 1:30 PM, Bradley Wagner bradley.wag...@hannonhill.com wrote: Thanks for the input. What we're seeing is that Velocity seems to be holding on to a lot of org.apache.velocity.runtime.parser.Token objects (around 5 million). We allow people to write arbitrary Velocity templates in our system and are evaluating them with: VelocityEngine.evaluate(Context context, Writer writer, String logTag, Reader reader) I was under the impression that Templates evaluated this way are inherently not cacheable. Is that the case? If that's not true, is there a way to control the cache Velocity is using for these? me too. just out of curiosity, what properties are you using for configuration? and can you tell any more about what class is holding onto those Tokens? On Thu, Jul 19, 2012 at 10:26 AM, Alex Fedotov a...@kayak.com wrote: I think that Velocity has one global hash table for macros from the *.vm libraries and that is more or less static for the life time of the Velocity engine. I wish there there was a mechanism to control the list of the *.vm files and their order of lookup for each individual merge (thread). This would facilitate macro overloads based on the context
Re: Macro caching and other caching
I think that Velocity has one global hash table for macros from the *.vm libraries and that is more or less static for the life time of the Velocity engine. I wish there there was a mechanism to control the list of the *.vm files and their order of lookup for each individual merge (thread). This would facilitate macro overloads based on the context. Unfortunately this feature is not available. I think the 1.7 behavior is (more or less): When template reference is found (i.e. #parse(x)) it is looked-up in the resource cache and if found there (with all the expiration checks, etc.) the parsed AST tree is used. If not found the template is loaded from the file, actually parsed and put into the cache. During the actual parsing process the macros that are defined in the template are put into the macro manager cache which is organized as: defining template name (name space) = macro name = AST macro code The AST is then rendered in the current context running #parse. When the time comes to call a macro there is a lookup process which can be influenced by some props, but the most general case is: 1. Lookup in the global *.vm files, if found use that. 2. Lookup in the same name space that calls the macro, if found use that. 3. Going back through the list of the #parse-d templates lookup in each name space on the stack. The stack can be actually very long too, for example #foreach($templ in [1..5]) #parse(${templ}.vtl) #end #mymacro() The lookup list here would contain: 1.vtl, 2.vtl, 3.vtl, 4.vtl, 5.vtl This is true even for cases where the name is the same: #foreach($item in [1..5]) #parse('item.vtl') #end The lookup list here would contain: item.vtl, item.vtl, item.vtl, item.vtl, item.vtl There is no attempt to optimize the lookup list and collapse the duplicates. Unfortunately 1.7 also had some nasty concurrency bugs there that had to do with clearing the name space of all the macros and repopulating it again on each parse which did not work at all with multiple threads. One thread could clear the name space while another was doing a lookup, etc. I think there was an effort to redesign that part in 2.0, but I have not looked at that yet. Alex On Wed, Jul 18, 2012 at 5:42 PM, Bradley Wagner bradley.wag...@hannonhill.com wrote: Hi, We recently made some changes to our software to use just a single VelocityEngine as per recommendations on this group. We ran into an issue where macros were all of the sudden being shared across template renders because we had not specified: velocimacro.permissions.allow.inline.local.scope = true. However, we also had not ever turned on caching in our props file with: class.resource.loader.cache = true. Does this mean that macros are cached separately from whatever is being cached in the class.resource.loader.cache cache? Is there any way to control that caching or is just using this property the way: velocimacro.permissions.allow.inline.local.scope = true One side effect of our recent changes is that the app seems to have an increased mem footprint. We're not *sure* it can be attributed to velocity but I was trying to see what kinds of things Velocity could be hanging on to and how much memory they might be taking up. Thanks!
Re: partial evaluation / removing directives
Another option may be rewriting the AST tree after the template is parsed and replacing some nodes with text or something else. I tried that on the side as an experiment to inject some security checks and collect profiling info for macros and templates. Alex On Fri, Jul 13, 2012 at 9:50 AM, Nathan Bubna nbu...@gmail.com wrote: On Thu, Jul 12, 2012 at 2:27 PM, Pete pete.devn...@gmail.com wrote: Hi all, I'm working with some velocity files where I want to partially evaluate them, such that the only things actually evaluated are #parse (includes of other velocity templates in the same directory) and $references to a resourceBundle variable passed in the context map. In essence, all this is doing is combining a number of velocity files into one master velocity file, and localizing any resource bundle references to a given locale. All the main velocity directives in the velocity file(s) should be left unevaluated- #set, #ifelse, #foreach etc. This way, the result could be redistributed and modified specific to a particular locale, with just one file instead of n based on the #parse structure. interesting challenge! glad i don't have to do it though. :) Up till now, I've been doing this in a somewhat roundabout way: 1. setting strict escape property to true 2. pre-processing the velocity templates by regexp replacing all instances of #if / #else/ #elseif/ #end / #foreach / #define / #break / #stop #set / #evaluate with \\#{$1} This adds a an escape character before each of these directives, and I can then call mergeTemplate on the result. It works OK, sometimes, but I still run into some parsing issues now and again (eg not a robust solution). It also seems kind of heavy handed to have to preprocess these files using a regular expression and saving them before velocity gets a handle on them. It would even be a bit better if I could do this by reading them in and doing the rgexp in-memory rather than on the saved files, then using evaluate instead of mergeTemplate. But I assume that would cause problems for the #parse directives. Why would evaluate cause problems for #parse?? If the engine is configured the same, the #parse should work the same whether you enter via file or string. I know velocity added a removeDirective() method in 1.6.2 which seems like it should be perfect for me - I could simply rip out all the directives but #parse. However, I tried the and it seems that it only works for certain directives, eg #foreach, #include, etc. More basic directives like #if and #elseif are not in the list of runtimedirectives, or even represented as Directive objects, so removing them doesn't work. Yeah, they are deep in the parser. Their structure doesn't work as a normal directive. Any suggestions on the best way to proceed with this? Would it be easy to change a few velocity files locally, recompile and get this behavior? Or is it sufficiently complex removing all these more basic directives that I'm better off continuing to try some kind of preprocessing/ escaping? You would have to redesign Velocity's parsing deeply. A major overhaul. You're best off preprocessing. Have you considered using a different template engine to do the first part (the parse and resourceBundle resolution)? Might be overkill, but might be easier, so long as the syntax has no overlap with VTL. thanks, Pete - To unsubscribe, e-mail: user-unsubscr...@velocity.apache.org For additional commands, e-mail: user-h...@velocity.apache.org
Re: partial evaluation / removing directives
Well, I did not get into the details, but the idea would be to replace the ASTIfStatement with a sequence of AST nodes that would output the #IF text followed by the result of rewriting the children, etc. followed by the #END text. I think the SimpleNode does not have a particularly friendly public interface to facilitate this kind of thing. I remember I had to resort to using reflection and accessing protected/private members directly. Alex As for the AST rewrite idea, if it was possible to Burn down nodes to their corresponding text something like that would work, However, wouldnt' that then possibly miss additional child elements in that AST tree? For instance a clause in an if statement which had a resourceBundle reference? I'm not too familiar with ASTs (been years since I dealt with those at school), maybe I can look at it a bit more today. thanks, Pete