Re: 2.0 question
Thanks. I'll review those StringBuffer uses. For the ASTStringLiteral, I see there's already a StringBuilderWriter in commons-io that I may borrow... On 11/12/2016 17:07, Alex Fedotov wrote: Great thank you. Actually I would recommend removing the StringWriter. StringWriter is using StringBuffer inside which is synchronized. In case of ASTStringLiteral there is no need to synchronize anything. There must be a Writer implementation based on StringBuilder instead. I have a run a search on the latest 2.0 code and it seems like there is a number of places where StringBuffer is used. Unless synchronization is required those usages should really be replaced with StringBuilder(s). = As far our usage of large string literal it was in a legacy framework that we had. It was creating a system of macros to render "tiles" on a page. Similar to this syntax (not real): @#PageSection(param1, param2) @#SubSection("tileName1") some html #end @#SubSection("tileName2") some other html #end #SubSection("tileName3", "/blah/blah/section.vtl") #end Velocity macros with body allow only one body block (special parameter really). We needed multiple named body blocks which we could render in the correct spots inside of the macro. We are no longer using this framework, but that is where we had large string literals appearing. I think we replaced the StringBuffer with some unsynchronized chunked implementation to avoid allocation of very large strings and unnecessary synchronzation. Alex On Sun, Dec 11, 2016 at 7:18 AM, Claude Brissonwrote: FYI, we got rid of the Executor pattern in the events API, and we now always provide the current Context when calling handlers. On 29/11/2016 23:25, Alex Fedotov wrote: [...] We have run into some other inefficient places. For example ASTStringLiteral is buffering the entire content in the StringWriter. It does not work very well for large templates. That code creates a writer which buffers up the whole thing, then does a toString() on it creating another copy. Then in some cases calls substring() that creates yet another copy. The substring belonged to an old workaround, it has been removed. The StringWriter buffering is only done when interpolation is needed (that is, when the string literal is enclosed in double quotes and has some $ or # inside). There could be some tricky ways of introducing some kind of lazy evaluation, that would resort to using the provided final writer when the value is meant to be rendered or to a buffered writer otherwise. But I'm not sure it is worth it, because it looks rather fragile and convoluted. Plus, you can generally avoid having big string literals. I don't know about your use case, but why can't something as: #set($foo = "#parse('big.vtl')") $foo be rewritten as: #parse('big.vtl') to avoid the buffering? Claude - To unsubscribe, e-mail: dev-unsubscr...@velocity.apache.org For additional commands, e-mail: dev-h...@velocity.apache.org
Re: 2.0 question
Great thank you. Actually I would recommend removing the StringWriter. StringWriter is using StringBuffer inside which is synchronized. In case of ASTStringLiteral there is no need to synchronize anything. There must be a Writer implementation based on StringBuilder instead. I have a run a search on the latest 2.0 code and it seems like there is a number of places where StringBuffer is used. Unless synchronization is required those usages should really be replaced with StringBuilder(s). = As far our usage of large string literal it was in a legacy framework that we had. It was creating a system of macros to render "tiles" on a page. Similar to this syntax (not real): @#PageSection(param1, param2) @#SubSection("tileName1") some html #end @#SubSection("tileName2") some other html #end #SubSection("tileName3", "/blah/blah/section.vtl") #end Velocity macros with body allow only one body block (special parameter really). We needed multiple named body blocks which we could render in the correct spots inside of the macro. We are no longer using this framework, but that is where we had large string literals appearing. I think we replaced the StringBuffer with some unsynchronized chunked implementation to avoid allocation of very large strings and unnecessary synchronzation. Alex On Sun, Dec 11, 2016 at 7:18 AM, Claude Brissonwrote: > FYI, we got rid of the Executor pattern in the events API, and we now > always provide the current Context when calling handlers. > > > On 29/11/2016 23:25, Alex Fedotov wrote: > [...] > >> We have run into some other inefficient places. For example >> ASTStringLiteral is buffering the entire content in the StringWriter. It >> does not work very well for large templates. >> That code creates a writer which buffers up the whole thing, then does a >> toString() on it creating another copy. Then in some cases calls >> substring() that creates yet another copy. >> > > The substring belonged to an old workaround, it has been removed. > > The StringWriter buffering is only done when interpolation is needed (that > is, when the string literal is enclosed in double quotes and has some $ or > # inside). There could be some tricky ways of introducing some kind of lazy > evaluation, that would resort to using the provided final writer when the > value is meant to be rendered or to a buffered writer otherwise. But I'm > not sure it is worth it, because it looks rather fragile and convoluted. > Plus, you can generally avoid having big string literals. I don't know > about your use case, but why can't something as: > > #set($foo = "#parse('big.vtl')") $foo > > be rewritten as: > > #parse('big.vtl') > > to avoid the buffering? > > > Claude > > >
Re: [tool] More tools reenginering
On 05/12/2016 19:51, Nathan Bubna wrote: On Mon, Dec 5, 2016 at 9:49 AM, Sergiu Dumitriuwrote: I agree with Michael here, this direction is against what "pure" Velocity is about. The generic tools shouldn't be allowed to fetch random resources off the internet. I'm with Claude here. Making powerful tools available is a good thing. If we were putting this in Engine, i'd protest. Even in VelocityView, clearly for webapps, it would seem an inappropriate default. But in GenericTools, i think it fits fine. They are to be generic, useful. Velocity is not just about MVC, not just used in applications. Exactly. Forbidding absolute URLs in view tools safe mode seems all we need to do to me. I'm also against propagating the dependency on DOM4J, a library which has been dead for ten years. Well, those who do the work should decide, but if i were doing the work, yeah, dom4j does smell a little. ;) Though arguably we can hardly be too critical of old, little-update libraries. Maybe I'll find the motivation to try to migrate the XmlTool. Getting rid of a sub-module would be nice. I'm OK with adding tools for working with JSON and XML, as long as they perform safe operations on local data, and use modern libraries for the generated data structures (org.json:json and the org.w3c.dom package, although it's not very user friendly). On 12/04/2016 07:57 AM, Michael Osipov wrote: Am 2016-12-02 um 10:01 schrieb Claude Brisson: Hi. On 01/12/2016 21:21, Michael Osipov wrote: While I understand you idea, I do think that introducing stuff like this a bad idea for several reasons: 1. Processing of structured, low-level data like XML, JSON, form data always belongs to a controller and not to the view layer. The view layer should always receive a minimal set of high-level structures to do its task. I'm well aware of this MVC design paradigm. But the underlying purpose is the separation of concerns, not the fact that the view should be fed its data like a baby. View layers have grown up, and pull models have proven their efficiency. Since they are more lightweight and flexible, they are far more maintainable. More specifically, let say for instance that someone wants to build a webapp and a native mobile app on a common model layer. He would typically publish his model in the form of an API returning JSON structures. They cannot be called low-level, because the raw data model has already been somehow digested in the API presentation logic. Each API author is trying to guarantee minimal ergonomics. So if I have, say, the following JSON: { '"books" : [ { "author": "Lewis Caroll", "title": "Alice in Wonderland" } , { "author":"Saint-Exupéry", "title":"le Petit Prince" } ] } what you're saying is that it's not high-level enough for the view? I can't agree. I do not consider this good application design unless I see a specific case where it truly makes sense. Having a browser/client-only app implies using JavaScript, thus Velocity will be a little of use. E.g., Sonatype Nexus does that. Render skeleton by Velocity, rest is done in JS. In this very example, this is not high-level. High-level for me is a complete abstraction of the serialization format, Java structures only. Pretty much like with Eclipse MOXy or Jackson, they support multiple formats and the templater user/designer does not really care about the format. While we may certainly agree on what's a definitely wrong design, I think there are several good designs and architectural styles, as there are many use cases. Formatting json/xml data is widely in the scope of a templating engine, whether client-side or server-side. Yes, you can choose to use a third party library to provide an abstraction of the serialization format, and in that case you won't need any XmlTool or JsonTool, but is it pertinent? - it's mainly a purely theoretical advantage: unless you are coding a very generic application whose data sources are not known in advance, you already know which data sources you use and in which format you get its data, and this format is very unlikely to change in the future for a given data source. - it does ignore format specificities (xml is a richer format than json, the formats are not always interchangeable). - it does add an extra layer, which comes with all its implied problematics (performances, dependencies, bugs, code generation, added complexity, ...) whereas a minimalistic and format-specific publication layer, because of its lightweight nature, doesn't impose all that. 2. You are turning a template engine into a scripting engine which Velocity is not. Since a bare scripting engine doesn't know how to do templating, I think you intended to say that I'm empowering Velocity with scripting abilities. Well... it's already the case. And another thing: I've seen environments where people made a complete mess of their view layer without using a single scripting functionality. My point
Re: 2.0 question
FYI, we got rid of the Executor pattern in the events API, and we now always provide the current Context when calling handlers. On 29/11/2016 23:25, Alex Fedotov wrote: [...] We have run into some other inefficient places. For example ASTStringLiteral is buffering the entire content in the StringWriter. It does not work very well for large templates. That code creates a writer which buffers up the whole thing, then does a toString() on it creating another copy. Then in some cases calls substring() that creates yet another copy. The substring belonged to an old workaround, it has been removed. The StringWriter buffering is only done when interpolation is needed (that is, when the string literal is enclosed in double quotes and has some $ or # inside). There could be some tricky ways of introducing some kind of lazy evaluation, that would resort to using the provided final writer when the value is meant to be rendered or to a buffered writer otherwise. But I'm not sure it is worth it, because it looks rather fragile and convoluted. Plus, you can generally avoid having big string literals. I don't know about your use case, but why can't something as: #set($foo = "#parse('big.vtl')") $foo be rewritten as: #parse('big.vtl') to avoid the buffering? Claude - To unsubscribe, e-mail: dev-unsubscr...@velocity.apache.org For additional commands, e-mail: dev-h...@velocity.apache.org