Class PathTemplate (2.4.0)

public class PathTemplate

Represents a path template.

Templates use the syntax of the API platform; see the protobuf of HttpRule for details. A template consists of a sequence of literals, wildcards, and variable bindings, where each binding can have a sub-path. A string representation can be parsed into an instance of PathTemplate, which can then be used to perform matching and instantiation.

Matching and instantiation deals with unescaping and escaping using URL encoding rules. For example, if a template variable for a single segment is instantiated with a string like "a/b", the slash will be escaped to "%2f". (Note that slash will not be escaped for a multiple-segment variable, but other characters will). The literals in the template itself are not escaped automatically, and must be already URL encoded.

Here is an example for a template using simple variables:


 PathTemplate template = PathTemplate.create("v1/shelves/{shelf}/books/{book}");
 assert template.matches("v2/shelves") == false;
 Map<String, String> values = template.match("v1/shelves/s1/books/b1");
 Map<String, String> expectedValues = new HashMap<>();
 expectedValues.put("shelf", "s1");
 expectedValues.put("book", "b1");
 assert values.equals(expectedValues);
 assert template.instantiate(values).equals("v1/shelves/s1/books/b1");
 

Templates can use variables which match sub-paths. Example:


 PathTemplate template = PathTemplate.create("v1/{name=shelves/*/books/*}";
 assert template.match("v1/shelves/books/b1") == null;
 Map<String, String> expectedValues = new HashMap<>();
 expectedValues.put("name", "shelves/s1/books/b1");
 assert template.match("v1/shelves/s1/books/b1").equals(expectedValues);
 }

Path templates can also be used with only wildcards. Each wildcard is associated with an implicit variable $n, where n is the zero-based position of the wildcard. Example:


 PathTemplate template = PathTemplate.create("shelves/*/books/*";
 assert template.match("shelves/books/b1") == null;
 Map<String, String> values = template.match("v1/shelves/s1/books/b1");
 Map<String, String> expectedValues = new HashMap<>();
 expectedValues.put("$0", s1");
 expectedValues.put("$1", "b1");
 assert values.equals(expectedValues);
 }

Paths input to matching can use URL relative syntax to indicate a host name by prefixing the host name, as in //somewhere.io/some/path. The host name is matched into the special variable #HOSTNAME_VAR. Patterns are agnostic about host names, and the same pattern can be used for URL relative syntax and simple path syntax:


 PathTemplate template = PathTemplate.create("shelves/*";
 Map<String, String> expectedValues = new HashMap<>();
 expectedValues.put(PathTemplate.HOSTNAME_VAR, "//somewhere.io");
 expectedValues.put("$0", s1");
 assert template.match("//somewhere.io/shelves/s1").equals(expectedValues);
 expectedValues.clear();
 expectedValues.put("$0", s1");
 assert template.match("shelves/s1").equals(expectedValues);
 }

For the representation of a resource name see TemplatedResourceName, which is based on path templates.

Inheritance

Object > PathTemplate

Static Fields

HOSTNAME_VAR

public static final String HOSTNAME_VAR

A constant identifying the special variable used for endpoint bindings in the result of #matchFromFullName(String). It may also contain protocol string, if its provided in the input.

Field Value
TypeDescription
String

Static Methods

create(String template)

public static PathTemplate create(String template)

Creates a path template from a string. The string must satisfy the syntax of path templates of the API platform; see HttpRule's proto source.

Parameter
NameDescription
templateString
Returns
TypeDescription
PathTemplate

createWithoutUrlEncoding(String template)

public static PathTemplate createWithoutUrlEncoding(String template)

Creates a path template from a string. The string must satisfy the syntax of path templates of the API platform; see HttpRule's proto source. Url encoding of template variables is disabled.

Parameter
NameDescription
templateString
Returns
TypeDescription
PathTemplate

Methods

decode(String path)

public List<String> decode(String path)

Matches the template into a list of positional values. The template must not be build from named bindings, but only contain wildcards. For each wildcard in the template, a value is returned at corresponding position in the list.

Parameter
NameDescription
pathString
Returns
TypeDescription
List<String>

encode(String[] values)

public String encode(String[] values)

Instantiates the template from the given positional parameters. The template must not be build from named bindings, but only contain wildcards. Each parameter position corresponds to a wildcard of the according position in the template.

Parameter
NameDescription
valuesString[]
Returns
TypeDescription
String

endsWithCustomVerb()

public boolean endsWithCustomVerb()

Returns true of this template ends with a custom verb.

Returns
TypeDescription
boolean

endsWithLiteral()

public boolean endsWithLiteral()

Returns true of this template ends with a literal.

Returns
TypeDescription
boolean

equals(Object obj)

public boolean equals(Object obj)
Parameter
NameDescription
objObject
Returns
TypeDescription
boolean
Overrides

hashCode()

public int hashCode()
Returns
TypeDescription
int
Overrides

instantiate(String[] keysAndValues)

public String instantiate(String[] keysAndValues)

Shortcut for #instantiate(Map) with a vararg parameter for keys and values.

Parameter
NameDescription
keysAndValuesString[]
Returns
TypeDescription
String

instantiate(Map<String,String> values)

public String instantiate(Map<String,String> values)

Instantiate the template based on the given variable assignment. Performs proper URL escaping of variable assignments.

Note that free wildcards in the template must have bindings of '$n' variables, where 'n' is the position of the wildcard (starting at 0). See the documentation of #match(String) for details.

Parameter
NameDescription
valuesMap<String,String>
Returns
TypeDescription
String

instantiatePartial(Map<String,String> values)

public String instantiatePartial(Map<String,String> values)

Same like #instantiate(Map) but allows for unbound variables, which are substituted using their original syntax. Example:


 PathTemplate template = PathTemplate.create("v1/shelves/{shelf}/books/{book}");
 Map<String, String> partialMap = new HashMap<>();
 partialMap.put("shelf", "s1");
 assert template.instantiatePartial(partialMap).equals("v1/shelves/s1/books/{book}");
 

The result of this call can be used to create a new template.

Parameter
NameDescription
valuesMap<String,String>
Returns
TypeDescription
String

match(String path)

public Map<String,String> match(String path)

Matches the path, returning a map from variable names to matched values. All matched values will be properly unescaped using URL encoding rules. If the path does not match the template, null is returned.

If the path starts with '//', the first segment will be interpreted as a host name and stored in the variable #HOSTNAME_VAR.

See the PathTemplate class documentation for examples.

For free wildcards in the template, the matching process creates variables named '$n', where 'n' is the wildcard's position in the template (starting at n=0). For example:


 PathTemplate template = PathTemplate.create("shelves/*/books/*");
 Map<String, String> expectedValues = new HashMap<>();
 expectedValues.put("$0", "s1");
 expectedValues.put("$1", "b1");
 assert template.match("shelves/s1/books/b2").equals(expectedValues);
 expectedValues.clear();
 expectedValues.put(HOSTNAME_VAR, "//somewhere.io");
 expectedValues.put("$0", "s1");
 expectedValues.put("$1", "b1");
 assert template.match("//somewhere.io/shelves/s1/books/b2").equals(expectedValues);
 

All matched values will be properly unescaped using URL encoding rules (so long as URL encoding has not been disabled by the #createWithoutUrlEncoding method).

Parameter
NameDescription
pathString
Returns
TypeDescription
Map<String,String>

matchFromFullName(String path)

public Map<String,String> matchFromFullName(String path)

Matches the path, where the first segment is interpreted as the host name regardless of whether it starts with '//' or not. Example:


 Map<String, String> expectedValues = new HashMap<>();
 expectedValues.put(HOSTNAME_VAR, "//somewhere.io");
 expectedValues.put("name", "shelves/s1");
 assert template("{name=shelves/*}").matchFromFullName("somewhere.io/shelves/s1")
          .equals(expectedValues);
 
Parameter
NameDescription
pathString
Returns
TypeDescription
Map<String,String>

matches(String path)

public boolean matches(String path)

Returns true if the template matches the path.

Parameter
NameDescription
pathString
Returns
TypeDescription
boolean

parentTemplate()

public PathTemplate parentTemplate()

Returns a template for the parent of this template.

Returns
TypeDescription
PathTemplate

parse(String path)

public TemplatedResourceName parse(String path)

Creates a resource name from this template and a path.

Parameter
NameDescription
pathString
Returns
TypeDescription
TemplatedResourceName

singleVar()

public String singleVar()

Returns the name of a singleton variable used by this template. If the template does not contain a single variable, returns null.

Returns
TypeDescription
String

subTemplate(String varName)

public PathTemplate subTemplate(String varName)

Returns a path template for the sub-path of the given variable. Example:


 PathTemplate template = PathTemplate.create("v1/{name=shelves/*/books/*}");
 assert template.subTemplate("name").toString().equals("shelves/*/books/*");
 

The returned template will never have named variables, but only wildcards, which are dealt with in matching and instantiation using '$n'-variables. See the documentation of #match(String) and #instantiate(Map), respectively.

For a variable which has no sub-path, this returns a path template with a single wildcard ('*').

Parameter
NameDescription
varNameString
Returns
TypeDescription
PathTemplate

toRawString()

public String toRawString()

Returns a raw version of the template as a string. This renders the template in its internal, normalized form.

Returns
TypeDescription
String

toString()

public String toString()

Returns a pretty version of the template as a string.

Returns
TypeDescription
String
Overrides

validate(String path, String exceptionMessagePrefix)

public void validate(String path, String exceptionMessagePrefix)

Throws a ValidationException if the template doesn't match the path. The exceptionMessagePrefix parameter will be prepended to the ValidationException message.

Parameters
NameDescription
pathString
exceptionMessagePrefixString

validatedMatch(String path, String exceptionMessagePrefix)

public Map<String,String> validatedMatch(String path, String exceptionMessagePrefix)

Matches the path, returning a map from variable names to matched values. All matched values will be properly unescaped using URL encoding rules. If the path does not match the template, throws a ValidationException. The exceptionMessagePrefix parameter will be prepended to the ValidationException message.

If the path starts with '//', the first segment will be interpreted as a host name and stored in the variable #HOSTNAME_VAR.

See the PathTemplate class documentation for examples.

For free wildcards in the template, the matching process creates variables named '$n', where 'n' is the wildcard's position in the template (starting at n=0). For example:


 PathTemplate template = PathTemplate.create("shelves/*/books/*");
 Map<String, String> expectedValues = new HashMap<>();
 expectedValues.put("$0", "s1");
 expectedValues.put("$1", "b1");
 assert template.validatedMatch("shelves/s1/books/b2", "User exception string")
            .equals(expectedValues);
 expectedValues.clear();
 expectedValues.put(HOSTNAME_VAR, "//somewhere.io");
 expectedValues.put("$0", "s1");
 expectedValues.put("$1", "b1");
 assert template.validatedMatch("//somewhere.io/shelves/s1/books/b2", "User exception string")
            .equals(expectedValues);
 

All matched values will be properly unescaped using URL encoding rules (so long as URL encoding has not been disabled by the #createWithoutUrlEncoding method).

Parameters
NameDescription
pathString
exceptionMessagePrefixString
Returns
TypeDescription
Map<String,String>

vars()

public Set<String> vars()

Returns the set of variable names used in the template.

Returns
TypeDescription
Set<String>

withoutVars()

public PathTemplate withoutVars()

Returns a template where all variable bindings have been replaced by wildcards, but which is equivalent regards matching to this one.

Returns
TypeDescription
PathTemplate