Camel
  1. Camel
  2. CAMEL-1226

String formatter / interpolator for dsl uris

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.0-M2
    • Component/s: camel-core
    • Labels:
      None

      Description

      Often one ends up with dsl expressions that build strings like:

       from("direct:start").to("ldap:localhost:" + port + "?base=" + query);
      

      Would in not be better to write

      from("direct:start").to("ldps:localhost:{1}?base={2}", port, query);
      

      , where "

      {1}" means "the first argument in the string varargs following. ( "{1}

      " could of course be replaced by some expression that you like the format of)

      To implementent this one could overload the from() and to() methods to accept a vararg array of Strings following the uri argument, and interpolate the uri with the varargs...

        Activity

        Hide
        Atle Prange added a comment -

        Good work!

        Show
        Atle Prange added a comment - Good work!
        Hide
        Claus Ibsen added a comment -

        New Revision: 753155

        Show
        Claus Ibsen added a comment - New Revision: 753155
        Hide
        Claus Ibsen added a comment -

        I decided for a short notation - toF and fromF

                        from("direct:start").toF("file://%s?fileName=%s", path, name);
        
                        fromF("file://%s?include=%s", path, pattern).toF("mock:%s", result);
        
        Show
        Claus Ibsen added a comment - I decided for a short notation - toF and fromF from( "direct:start" ).toF( "file: //%s?fileName=%s" , path, name); fromF( "file: //%s?include=%s" , path, pattern).toF( "mock:%s" , result);
        Hide
        Claus Ibsen added a comment -

        +1 to buildUri

        Show
        Claus Ibsen added a comment - +1 to buildUri
        Hide
        Atle Prange added a comment -

        I agree with you.

        Maybe buildUri() would be appropriate?

        Show
        Atle Prange added a comment - I agree with you. Maybe buildUri() would be appropriate?
        Hide
        james strachan added a comment -

        the issue with 'format' is it reads like you are formatting the message - rather than formatting the URI string used to send a message to somewhere. So I think something like toFormat() or toUriFormat() is cleaner

        Show
        james strachan added a comment - the issue with 'format' is it reads like you are formatting the message - rather than formatting the URI string used to send a message to somewhere. So I think something like toFormat() or toUriFormat() is cleaner
        Hide
        Atle Prange added a comment -

        That seems to do the trick, with the plus that it is already part of the
        JDK, and one could use some String.format static import elsewhere and
        still keep the same conventions.
        If i could choose i would pick the method name "format()" instead of
        "toFormat()", it seems more elegant to me....

        Show
        Atle Prange added a comment - That seems to do the trick, with the plus that it is already part of the JDK, and one could use some String.format static import elsewhere and still keep the same conventions. If i could choose i would pick the method name "format()" instead of "toFormat()", it seems more elegant to me....
        Hide
        james strachan added a comment - - edited

        I'm thinking that we'd add something like this

        public Builder toFormat(String format, Object... args) {
          return to(String.format(format, args));
        }
        

        Then use the same encoding conventions as the String.format() method using the JDK standard format syntax

        Show
        james strachan added a comment - - edited I'm thinking that we'd add something like this public Builder toFormat( String format, Object ... args) { return to( String .format(format, args)); } Then use the same encoding conventions as the String.format() method using the JDK standard format syntax
        Hide
        Atle Prange added a comment -

        I have seen so many different ways of representing the placeholder, but
        why not use a java API standard.

        Other examples are EL: #

        {0}

        , #

        {1}

        ; StringFormat: %s, %s...

        Show
        Atle Prange added a comment - I have seen so many different ways of representing the placeholder, but why not use a java API standard. Other examples are EL: # {0} , # {1} ; StringFormat: %s, %s...
        Hide
        james strachan added a comment -

        If we do add a helper method - we should probably name it in line with the use of the static import.

        so

        from("direct:start").
          to( format( "ldps:localhost:{1}?base={2}", port, query) );
        

        or

        from("direct:start").
          toFormat( "ldps:localhost:{1}?base={2}", port, query);
        
        Show
        james strachan added a comment - If we do add a helper method - we should probably name it in line with the use of the static import. so from( "direct:start" ). to( format( "ldps:localhost:{1}?base={2}" , port, query) ); or from( "direct:start" ). toFormat( "ldps:localhost:{1}?base={2}" , port, query);
        Hide
        james strachan added a comment -

        BTW String.format() is part of the JDK now. So with a static import code would look like this...

        from("direct:start").to( format( "ldps:localhost:{1}?base={2}", port, query) );
        

        The great thing about this approach is you can use the format() method for any parameter that takes a string. It also works with varargs.

        from("direct:start").
          to( format( "ldps:localhost:{1}?base={2}", port, query).
               format("jms:{1}", somequeue) );
        
        Show
        james strachan added a comment - BTW String.format() is part of the JDK now. So with a static import code would look like this... from( "direct:start" ).to( format( "ldps:localhost:{1}?base={2}" , port, query) ); The great thing about this approach is you can use the format() method for any parameter that takes a string. It also works with varargs. from( "direct:start" ). to( format( "ldps:localhost:{1}?base={2}" , port, query). format( "jms:{1}" , somequeue) );
        Hide
        james strachan added a comment -

        The spring property place holders works already AFAIK as you say

        <endpoint id="foo" uri="ldps:localhost:${port}?base=${query}"/>
        
        Show
        james strachan added a comment - The spring property place holders works already AFAIK as you say <endpoint id= "foo" uri= "ldps:localhost:${port}?base=${query}" />
        Hide
        Claus Ibsen added a comment -

        I anticipate you are thinking of using java.text.MessageFormat since the placeholders is what it's using.

        Not a bad idea with the builder method. I dont think many end users is familiar with the intepolate term, so I kinda like:

        • toUri
        • buildUri
        • formatUri
          Or what is a good name.

        For Spring DSL end users should use <endpoint id="foo" uri="xxx"/> where you can use spring property placeholders
        And then use ref for this endpoint. <to ref="foo"/>

        Show
        Claus Ibsen added a comment - I anticipate you are thinking of using java.text.MessageFormat since the placeholders is what it's using. Not a bad idea with the builder method. I dont think many end users is familiar with the intepolate term, so I kinda like: toUri buildUri formatUri Or what is a good name. For Spring DSL end users should use <endpoint id="foo" uri="xxx"/> where you can use spring property placeholders And then use ref for this endpoint. <to ref="foo"/>
        Hide
        Atle Prange added a comment -

        i guess the ugly way would be to define a new method that takes the
        string and vararg list that interpolates the string with the arguments.
        Suggestions for method names: uri(String templates, Objec ... values),
        interpolate(...), buildUri(...))

        from("direct:start").to( intepolate( "ldps:localhost:{1}?base={2}", port, query) );
        
        Show
        Atle Prange added a comment - i guess the ugly way would be to define a new method that takes the string and vararg list that interpolates the string with the arguments. Suggestions for method names: uri(String templates, Objec ... values), interpolate(...), buildUri(...)) from( "direct:start" ).to( intepolate( "ldps:localhost:{1}?base={2}" , port, query) );
        Hide
        Claus Ibsen added a comment -

        And besides we might wanna thing if we can do something for this as well in the Spring DSL

        Show
        Claus Ibsen added a comment - And besides we might wanna thing if we can do something for this as well in the Spring DSL
        Hide
        Claus Ibsen added a comment -

        I think the builder for to already have varargs for a pipeline with N destinations.

        from("direct:start").to("log:foo", "bean:validate", "bean:process", "mail:xxxx")
        

        So it can't really be done without adding some rules such as if the first parameter is a string and it has

        {1}

        placeholders then these remaining parameters are for these placeholders.
        Or something like that.

        Any ideas?

        But the idea is very cool and something I would like to have as well. Making the route much easier to read as well. I kinda miss Groovy and it's $ support for Strings. Damm Java starts to feel "old"

        Show
        Claus Ibsen added a comment - I think the builder for to already have varargs for a pipeline with N destinations. from( "direct:start" ).to( "log:foo" , "bean:validate" , "bean:process" , "mail:xxxx" ) So it can't really be done without adding some rules such as if the first parameter is a string and it has {1} placeholders then these remaining parameters are for these placeholders. Or something like that. Any ideas? But the idea is very cool and something I would like to have as well. Making the route much easier to read as well. I kinda miss Groovy and it's $ support for Strings. Damm Java starts to feel "old"

          People

          • Assignee:
            Claus Ibsen
            Reporter:
            Atle Prange
          • Votes:
            1 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development