damnhandy / Handy-URI-Templates

A Java URI Template processor implementing RFC6570

Home Page:https://damnhandy.github.io/Handy-URI-Templates/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RFC6570UriTemplate.expand shouldn't fail when no variables are present

opened this issue · comments

Currently RFC6570UriTemplate.expand fails if no variables are present. This requires an if statement to guard, which offers little value to the user. Can you just return the original string when no variables are set?

Do you have a test case that demonstrates what you're experiencing?

sure. here's the base case

 UriTemplate.expand("https://foo.com:8080", ImmutableMap.<String, Object>of());

Ok, that's actually failing since you are passing in a URI not a URI template. The error is that no expressions are found in the initial string. The processor hasn't even looked at the variable Map yet. I have double check the spec, but at first glance, it doesn't appear to specify how to handle a case like this.

well, specs or no specs, seems sensible to allow a base case, right?

in which case, just return the original string.

right now, I'm happy about the uri template syntax, except I need to wrap
it with a couple dozen lines of guards. would be nice not to have to do
stuff like this.

   private static String expandTemplate(String template, Map<String,
Object> variables) {
      boolean hasVars = false;
      boolean inVar = false;
      StringBuilder builder = new StringBuilder();
      for (char c : Lists.charactersOf(template)) {
         switch (c) {
         case '{':
            inVar = hasVars = true;
            builder.append(c);
            break;
         case '}':
            inVar = false;
            builder.append(c);
            break;
         case '-':
            // jclouds variable names aren't currently compliant with
RFC6570, as they tend
            // to have hyphens in them. hoping for
https://github.com/damnhandy/Handy-URI-Templates/issues/11
            if (inVar) {
               builder.append('_');
               break;
            }
         default:
            builder.append(c);
         }
      }

      // correct input variable map to use underscores due to RFC6570
non-compliance
      variables = Maps2.transformKeys(variables, hyphenToUnderscore);

      // special case to be eliminated if
https://github.com/damnhandy/Handy-URI-Templates/issues/12 resolves
      if (hasVars)
         return UriTemplate.expand(builder.toString(), variables);
      return template;
   }

There's ironically less code to implement the template expansion directly vs work around the constraints. when we start using more sophisticated (> level 1) uri templates, I'll come back here for a look. Regardless, thanks for looking at these issues!

Looking at more, it's clear that the exception handling needs to be refined a bit so that it's a bit more obvious how to handle these cases. However, the URI template you are passing in is not valid and an exception is being raise to indicate that. Technically you're code is checking that the template contains expressions, hence some of my confusion. Variables are the things you pass in to the UriTemplate. Rather than checking if the UriTemplate has expressions, you could catch a UriTemplateParseException to see if the template didn't pass validation.

I'm making a lot of changes to the API for 1.2 as that release will support reverse mapping. With any luck, I'll get that out before years end.

@jclouds, I've been going through the past issues and revisiting these issues. I think you'll find that the 2.0 alpha now gives you the behavior you want. Sans the hyphen of course ;)