commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Scott Sanders" <>
Subject RE: Thoughts on StringUtils architecture
Date Tue, 11 Dec 2001 20:04:54 GMT
But then you would just use Velocity :)


> -----Original Message-----
> From: Laird Nelson [] 
> Sent: Tuesday, December 11, 2001 11:07 AM
> To:
> Subject: Thoughts on StringUtils architecture
> Here's an architectural thought that occurred to me.  It's 
> related to the overall architecture of StringUtils.
> When munging text, frequently you want to work on isolated 
> Strings. But just as frequently you want to work on character 
> streams, which read their stuff in chunks.  What happens if 
> you read a chunk, and the last two characters of that chunk 
> are the *first* two characters of your three-character-long 
> String-to-be-escaped?  Passing it to a stateless
> escape() method, for example, won't escape the last two 
> characters, because of course it doesn't know that the third 
> one is on the way.
> The architecture I've found that works pretty well--although 
> it seems like overkill when presented this way, so bear with 
> me--is something like this (apologies if anyone finds this 
> boringly obvious; it was a Moment for me and my slow brain :-)):
> Suppose you want to interpolate variable references ${like} 
> ${this} and replace them with, say, 
> System.getProperty("like") and System.getProperty("this").  
> And suppose you want to do that work so that you can invoke 
> it from a standalone class like StringUtils or a Reader class.
> The best bet is to implement a parser that takes in a 
> StringBuffer (the raw text), some kind of value object that 
> holds the parser's state, and that returns something 
> convenient, like the StringBuffer interpolated so far, or the 
> new state.  java.text.ParsePosition is a bare bones example 
> of this sort of thing, used for java.text.MessageFormat etc.
> That way if you call the parser several times on chunks of 
> text that look, for example, like this:
>   Chunk 1: Hi, there, ${us
>   Chunk 2:}!  Earn free $
>   Chunk 3: $$!
> ...the parser will report, via the state object, whether it's 
> done with a piece yet, and if you're in a Reader you can pay 
> attention to this and if you're in, say, StringUtils, you can 
> ignore it.
> Now if you invoke the parser from a standalone class like 
> StringUtils, you just ignore the fact that it's not done yet, 
> and you get, as
> results:
>   Result of munging chunk 1: Hi, there, ${us
>   Result of munging chunk 2:}!  Earn free $
>   Result of munging chunk 3: $$!
> ...i.e. in this stupid case the same as what you put in.  But 
> if you invoke the parser via a Reader using the same chunks, 
> you can see that you could build the Reader in such a way to 
> have a cache that would let you return this:
>   Result of three read(char[], int, int) calls: Hi, there, lnelson! 
> Earn free $$$!
> So in general for greater-than-single-character munging, it pays to
> create:
>   1. A parser where you pass in its initial state each time you
>      parse/munge the raw text
>   2. A standalone method/class that simply invokes the parser once on
>      the supplied String and ignores whether it's done or not
>   3. A reader (or writer, or both) that feeds the parser as little as
>      the parser needs to complete his work
> I bring this up simply to call attention to it--basically to 
> point out that one should remember character streams when one 
> is building String-whacking routines such as escape().
> Cheers,
> Laird
> __________________________________________________
> Do You Yahoo!?
> Check out Yahoo! Shopping and Yahoo! Auctions for all of
> your unique holiday gifts! Buy at
> or bid at
> --
> To unsubscribe, e-mail:   
> <mailto:commons-dev->>
> For 
> additional commands, 
> e-mail: <>

To unsubscribe, e-mail:   <>
For additional commands, e-mail: <>

View raw message