groovy
  1. groovy
  2. GROOVY-2505

Need to be able to either convert a String to a GString or to evaluate a String.

    Details

    • Type: Improvement Improvement
    • Status: Open Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.5.1
    • Fix Version/s: None
    • Component/s: groovy-jdk
    • Labels:
      None
    • Number of attachments :
      0

      Description

      Several times it has been asked on the mailing list on how to either convert a String to a GString or to evaluate a String as a GString. The need arises when a String comes in from an external source and contains a GString expression, for example an XML file or a Configuration file. Currently one needs to either invoke the GroovyShell or the SimpleTemplateEngine to accomplish the task. In both cases this takes several lines of code and is not intuitively obvious.

      One could ether add a GDK method to String such as "evaluate" (which in my humble opinion would be the nicest) or provide a conversion of the form "String as GString"

        Activity

        Hide
        Brian Hart added a comment -

        Any new information on this or best practices to for work arounds? In particular any example work around using SimpleTemplateEngine when reading from an XML File?

        Show
        Brian Hart added a comment - Any new information on this or best practices to for work arounds? In particular any example work around using SimpleTemplateEngine when reading from an XML File?
        Hide
        Paul King added a comment -

        There are some possible workarounds. Do you have a SimpleTemplateEngine example that you know doesn't work that you could provide as an example? Small is good!

        Show
        Paul King added a comment - There are some possible workarounds. Do you have a SimpleTemplateEngine example that you know doesn't work that you could provide as an example? Small is good!
        Hide
        Russel Winder added a comment -

        Using a template engine is often too heavyweight a way of doing things. And doing things like:

        x = '${System.properties."user.home"}'
        y = ( new GroovyShell ( ) ).evaluate ( '"' + x + '"' )
        println ( y )
        

        seems a bit heavyhanded and ugly.

        Show
        Russel Winder added a comment - Using a template engine is often too heavyweight a way of doing things. And doing things like: x = '${ System .properties. "user.home" }' y = ( new GroovyShell ( ) ).evaluate ( ' "' + x + '" ' ) println ( y ) seems a bit heavyhanded and ugly.
        Hide
        Guillaume Laforge added a comment -

        In a script, it's less heavy-handed already:

        def x = '${System.properties."user.home"}'
        def y = evaluate(/"$x"/)
        println y
        ​
        Show
        Guillaume Laforge added a comment - In a script, it's less heavy-handed already: def x = '${ System .properties. "user.home" }' def y = evaluate(/ "$x" /) println y ​
        Hide
        K Smith added a comment - - edited
        x = '${System.properties."user.home"}'
        // y = (x as GString).toString()
        y = new groovy.text.GStringTemplateEngine().createTemplate(x).make().writeTo(new StringWriter()).toString()
        

        Is there really nothing simpler than this (outside of a script)?

        Show
        K Smith added a comment - - edited x = '${ System .properties. "user.home" }' // y = (x as GString).toString() y = new groovy.text.GStringTemplateEngine().createTemplate(x).make().writeTo( new StringWriter()).toString() Is there really nothing simpler than this (outside of a script)?
        Hide
        Guillaume Laforge added a comment -

        You can use the Eval class:

        def gs = Eval.me('"${System.properties."user.home"}"')
        assert gs instanceof GString
        println gs
        
        Show
        Guillaume Laforge added a comment - You can use the Eval class: def gs = Eval.me(' "${ System .properties." user.home "}" ') assert gs instanceof GString println gs
        Hide
        Paul King added a comment -

        Depending on your scenario, you might also be able to use the following trick:

        String home = System.properties."user.home"
        def basedir = 'Downloads'
        def gs = GString.EMPTY + home + File.separator + "$basedir"
        assert gs instanceof GString
        println gs
        

        The 'basedir' part becomes a param for the GString but relies on the basedir GString being part of the compiled code/script.

        Show
        Paul King added a comment - Depending on your scenario, you might also be able to use the following trick: String home = System .properties. "user.home" def basedir = 'Downloads' def gs = GString.EMPTY + home + File.separator + "$basedir" assert gs instanceof GString println gs The 'basedir' part becomes a param for the GString but relies on the basedir GString being part of the compiled code/script.
        Hide
        Erick Dovale added a comment - - edited

        Lets say I have the following code in a template:

        <% 
        import static java.net.URLEncoder.encode 
        def enc(url, times=1){
        	def aUrl = GString.EMPTY + url
        	println aUrl.class
        	String result = aUrl.toString()
        	println result
        	for (i in 1..times){
        		result = encode(result)
        	}
        	result
        }
        %> 
        http://click.linksynergy.com/fs-bin/stat?id=abcd&offerid=1234&type=0&subid=0&tmpid=12346&u1=${user.id}&RD_PARM1=${enc('http://itunes.apple.com/us/app/id${app.id}?mt=8&uo=123&partnerId=1234',2)}
        

        I need to replace $

        {app.id}

        in the parameter to the enc method defined above. You can see what I have been trying to no avail.
        What is the way to do this?

        Btw, I am using a SimpleTemplateEngine to run the script above from Java code. app and user are passed in.

        Thanks a lot.

        Show
        Erick Dovale added a comment - - edited Lets say I have the following code in a template: <% import static java.net.URLEncoder.encode def enc(url, times=1){ def aUrl = GString.EMPTY + url println aUrl.class String result = aUrl.toString() println result for (i in 1..times){ result = encode(result) } result } %> http: //click.linksynergy.com/fs-bin/stat?id=abcd&offerid=1234&type=0&subid=0&tmpid=12346&u1=${user.id}&RD_PARM1=${enc('http://itunes.apple.com/us/app/id${app.id}?mt=8&uo=123&partnerId=1234',2)} I need to replace $ {app.id} in the parameter to the enc method defined above. You can see what I have been trying to no avail. What is the way to do this? Btw, I am using a SimpleTemplateEngine to run the script above from Java code. app and user are passed in. Thanks a lot.
        Hide
        blackdrag blackdrag added a comment -

        can't you just use string replacement here?

        Show
        blackdrag blackdrag added a comment - can't you just use string replacement here?

          People

          • Assignee:
            Unassigned
            Reporter:
            Erik Husby
          • Votes:
            13 Vote for this issue
            Watchers:
            17 Start watching this issue

            Dates

            • Created:
              Updated: