All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.damnhandy.uri.template.UriTemplateBuilder Maven / Gradle / Ivy

Go to download

Handy URI Templates is a RFC6570 compliant URI template processor. The library allows clients to utilize templatized URIs and inject replacement variables to expand the template into a URI. The library sports a fluent API, ability to plugin custom object renderers, and supports all levels of URI templates.

The newest version!
/*
 *
 *
 */
package com.damnhandy.uri.template;

import com.damnhandy.uri.template.impl.Modifier;
import com.damnhandy.uri.template.impl.Operator;
import com.damnhandy.uri.template.impl.UriTemplateParser;
import com.damnhandy.uri.template.impl.VarSpec;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;

/**
 * 

* A utility class used for programatically generating a {@link UriTemplate}. * The class can be used as follows: *

*
 * UriTemplate template = UriTemplate.buildFromTemplate("http://example.com")
 *                                   .literal("/foo")
 *                                   .path(var("thing1"), var("explodedThing", true))
 *                                   .fragment(var("prefix", 2))
 *                                   .build();
 * 
*

* This code will return a {@link UriTemplate} with the following value: *

*
 * http://example.com/foo{/thing1,explodedThing*}{#prefix:2}
 * 
* * @author Ryan J. McDonough * @version $Revision: 1.1 $ */ public final class UriTemplateBuilder { /** * The URI expression */ private LinkedList components = new LinkedList(); /** * */ private DateTimeFormatter defaultDateTimeFormatter = null; /** * */ private Map values = null; UriTemplateBuilder() { this.components = new LinkedList(); } /** * Create a new UriTemplateBuilder. * * @param templateString the initial URI template string */ UriTemplateBuilder(String templateString) throws MalformedUriTemplateException { this.components = new UriTemplateParser().scan(templateString); } /** * Create a new UriTemplateBuilder. * * @param template the initial UriTemplate */ UriTemplateBuilder(UriTemplate template) throws MalformedUriTemplateException { this(template.getTemplate()); this.values = template.getValues(); this.defaultDateTimeFormatter = template.defaultDateTimeFormatter; } /** * @param dateFormatString the date format to use internally * @return the UriTemplateBuilder * @since 2.0 */ public UriTemplateBuilder withDefaultDateFormat(String dateFormatString) { return this.withDefaultDateFormat(DateTimeFormat.forPattern(dateFormatString)); } private UriTemplateBuilder withDefaultDateFormat(DateTimeFormatter dateTimeFormatter) { defaultDateTimeFormatter = dateTimeFormatter; return this; } /** * @param dateFormat the date format to use internally * @return the UriTemplateBuilder * @since 2.0 * @deprecated replaced by {@link #withDefaultDateFormat(String) withDefaultDateFormat} */ @Deprecated public UriTemplateBuilder withDefaultDateFormat(DateFormat dateFormat) { if (!(dateFormat instanceof SimpleDateFormat)) { throw new IllegalArgumentException( "The only supported subclass of java.text.DateFormat is java.text.SimpleDateFormat"); } defaultDateTimeFormatter = DateTimeFormat.forPattern(((SimpleDateFormat) dateFormat).toPattern()); return this; } void addComponent(UriTemplateComponent component) { this.components.add(component); } void addComponents(Collection compoments) { this.components.addAll(compoments); } /** * Appends a {@link Literal} value to the {@link UriTemplate}. The following * code: *

*

     * UriTemplate template = UriTemplate.buildFromTemplate("http://example.com")
     *                                   .literal("/foo")
     *                                   .build();
     * 
*

* Will generate the following template: *

*

     * http://example.com/foo
     * 
*

* Note that this particular example has no expressions, so it's not a valid URI template. * * @param string the literal string * @return */ public UriTemplateBuilder literal(String string) { if (string == null) { return this; } addComponent(new Literal(string, 0)); return this; } /** * @param varSpec the varspec name * @return the array of varspecs */ private static VarSpec[] toVarSpec(String... varSpec) { VarSpec[] vars = new VarSpec[varSpec.length]; for (int i = 0; i < varSpec.length; i++) { vars[i] = var(varSpec[i]); } return vars; } /** * Appends a template expression using no operator. The following * code: *

     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .simple("foo")
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{foo}
     * 
* * @param var the name of the variable * @return the UriTemplateBuilder */ public UriTemplateBuilder simple(String... var) { simple(toVarSpec(var)); return this; } /** * Appends a template expression using no operator but with an optional * modifier. The following code: *
     * import static com.damnhandy.uri.template.UriTemplateBuilder.var;
     *
     * ...
     *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .simple(var("foo",true))
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{foo*}
     * 
* * @param var the varspec * @return the UriTemplateBuilder */ public UriTemplateBuilder simple(VarSpec... var) { addComponent(Expression.simple(var).build()); return this; } /** * Appends a template expression using the reserved operator (+). The following * code: *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .reserved("foo")
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{+foo}
     * 
* * @param var the varspec name * @return the UriTemplateBuilder */ public UriTemplateBuilder reserved(String... var) { reserved(toVarSpec(var)); return this; } /** * Appends a template expression using the reserved operator (+) along * with an optional modifier. The following code: *
     * import static com.damnhandy.uri.template.UriTemplateBuilder.var;
     *
     * ...
     *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .reserved(var("foo",1))
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{+foo:1}
     * 
* * @param var the varspec * @return the UriTemplateBuilder */ public UriTemplateBuilder reserved(VarSpec... var) { addComponent(Expression.reserved(var).build()); return this; } /** * Appends a template expression using the fragment operator (#). The * following code: *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .fragement("foo")
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{#foo}
     * 
* * @param var the varspec name * @return the UriTemplateBuilder * @throws UriTemplateBuilderException if you attempt to add more than one fragment expression, a UriTemplateBuilderException will be raised */ public UriTemplateBuilder fragment(String... var) throws UriTemplateBuilderException { fragment(toVarSpec(var)); return this; } /** * Appends a template expression using the fragment operator (#) with a * modifier. The following code: *
     * import static com.damnhandy.uri.template.UriTemplateBuilder.var;
     *
     * ...
     *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .fragement(var("foo", 1))
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{#foo:1}
     * 
* * @param var the varspec * @return the UriTemplateBuilder * @throws UriTemplateBuilderException if you attempt to add more than one fragment expression, a UriTemplateBuilderException will be raised */ public UriTemplateBuilder fragment(VarSpec... var) throws UriTemplateBuilderException { if (hasExpressionWithOperator(Operator.FRAGMENT)) { throw new UriTemplateBuilderException("The template already has a fragment expression and this would not result in a valid URI"); } addComponent(Expression.fragment(var).build()); return this; } /** * Scans the components for an expression with the specified operator. * * @param op * @return */ private boolean hasExpressionWithOperator(Operator op) { for (UriTemplateComponent c : components) { if (Expression.class.isInstance(c)) { Expression e = (Expression) c; if (e.getOperator() == op) { return true; } } } return false; } /** * Appends a template expression using the label (.) operator. The following * code: *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .label("foo")
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{.foo}
     * 
* * @param var the varspec name * @return the UriTemplateBuilder */ public UriTemplateBuilder label(String... var) { label(toVarSpec(var)); return this; } /** * Appends a template expression using the label (.) operator and modifier. * The following code: *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .label(var("foo", true))
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{.foo*}
     * 
* * @param var the varspec * @return the UriTemplateBuilder */ public UriTemplateBuilder label(VarSpec... var) { addComponent(Expression.label(var).build()); return this; } /** * Appends a template expression using the matrix (;) operator. The following * code: *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .matrix("foo")
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{;foo}
     * 
* * @param var the varspec name * @return the UriTemplateBuilder */ public UriTemplateBuilder matrix(String... var) { matrix(toVarSpec(var)); return this; } /** * Appends a template expression using the matrix (;) operator and modifier. * The following code: *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .matrix(var("foo", true))
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{;foo*}
     * 
* * @param var the varspec * @return the UriTemplateBuilder */ public UriTemplateBuilder matrix(VarSpec... var) { addComponent(Expression.matrix(var).build()); return this; } /** * Appends a template expression using the path (/) operator. The following * code: *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com")
     *                   .path("foo")
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com{/foo}
     * 
* * @param var the varspec name * @return the UriTemplateBuilder */ public UriTemplateBuilder path(String... var) { path(toVarSpec(var)); return this; } /** * Appends a template expression using the path (/) operator and modifier. * The following code: *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com")
     *                   .path(var("foo", 1))
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com{/foo:1}
     * 
* * @param var the varspec * @return the UriTemplateBuilder */ public UriTemplateBuilder path(VarSpec... var) { addComponent(Expression.path(var).build()); return this; } /** * Appends a template expression using the query (?) operator. The following * code: *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .query("foo")
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{?foo}
     * 
* * @param var the varspec name * @return the UriTemplateBuilder */ public UriTemplateBuilder query(String... var) { query(toVarSpec(var)); return this; } /** * Appends a template expression using the query (?) operator and * and optional modifier. The following * code: *
     * import static com.damnhandy.uri.template.UriTemplateBuilder.var;
     *
     * ...
     *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .query(var("foo",1))
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{?foo:1}
     * 
* * @param var the varspec * @return the UriTemplateBuilder */ public UriTemplateBuilder query(VarSpec... var) { addComponent(Expression.query(var).build()); return this; } /** * Appends a template expression using the form-style query continuation. The following * code: *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .continuation("foo")
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{&foo}
     * 
* * @param var the varspec name * @return the UriTemplateBuilder */ public UriTemplateBuilder continuation(String... var) { return continuation(toVarSpec(var)); } /** * Appends a template expression using the form-style query continuation and * and optional modifier. The following * code: *
     * import static com.damnhandy.uri.template.UriTemplateBuilder.var;
     *
     * ...
     *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .query(var("foo",1))
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/{&foo:1}
     * 
* * @param var the varspec * @return the UriTemplateBuilder */ public UriTemplateBuilder continuation(VarSpec... var) { addComponent(Expression.continuation(var).build()); return this; } /** * Parses the template and appends the parsed components * to the builder. The following * code: *
     * import static com.damnhandy.uri.template.UriTemplateBuilder.var;
     *
     * ...
     *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .template("foo/{id}{?filter}")
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/foo/{id}{?filter}
     * 
* * @param template the uri template * @return the UriTemplateBuilder */ public UriTemplateBuilder template(UriTemplate... template) { for(UriTemplate t : template) { addComponents(t.getComponents()); } return this; } /** * Parses the template and appends the parsed components * to the builder. The following * code: *
     * import static com.damnhandy.uri.template.UriTemplateBuilder.var;
     *
     * ...
     *
     * UriTemplate template =
     *        UriTemplate.buildFromTemplate("http://example.com/")
     *                   .template("foo/{id}{?filter}")
     *                   .build();
     * 
* Will generate the following URI Template string: *
     * http://example.com/foo/{id}{?filter}
     * 
* * @param template the uri template string * @return the uri template builder */ public UriTemplateBuilder template(String... template) { UriTemplateParser parser = new UriTemplateParser(); for(String t : template) { addComponents(parser.scan(t)); } return this; } /** * Returns an array of the components in the Builder. * @return array of the components in the Builder */ public UriTemplateComponent[] getComponents() { return this.components.toArray(new UriTemplateComponent[components.size()]); } /** *

* Generates a {@link UriTemplate} instance from the builder. *

* * @return the UriTemplate * @since 2.0 */ public UriTemplate build() throws MalformedUriTemplateException { UriTemplate template = new UriTemplate(this.components); if (this.values != null) { template.set(values); } if (defaultDateTimeFormatter != null) { template.defaultDateTimeFormatter = defaultDateTimeFormatter; } return template; } /** * Adds a variable name to the expression. *

*

     * var("foo");
     * 
*

* Will yield the following expression: *

     * {foo}
     * 
* * @param varName the varspec name * @return the {@link com.damnhandy.uri.template.impl.VarSpec} for the specified name */ public static VarSpec var(String varName) { return var(varName, Modifier.NONE, null); } /** * Adds a variable name to the expression with an explode modifier. *

*

     * var("foo",true);
     * 
*

* Will yield the following expression: *

     * {foo*}
     * 
* * @param varName the varspec name * @param explode boolean to indicate that this VarSpec should use the explode modifer * @return the {@link com.damnhandy.uri.template.impl.VarSpec} for the specified name */ public static VarSpec var(String varName, boolean explode) { if (explode) { return var(varName, Modifier.EXPLODE, null); } return var(varName, Modifier.NONE, null); } /** * Adds a variable name to the expression with a prefix modifier. *

*

     * var("foo",2);
     * 
*

* Will yield the following expression: *

     * {foo:2}
     * 
* * @param varName the varspec name * @param prefix the prefix position * @return the {@link com.damnhandy.uri.template.impl.VarSpec} for the specified name */ public static VarSpec var(String varName, int prefix) { return var(varName, Modifier.PREFIX, prefix); } /** * @param varName the varspec name * @param modifier the modifier * @param position the prefix position * @return the {@link com.damnhandy.uri.template.impl.VarSpec} for the specified name */ private static VarSpec var(String varName, Modifier modifier, Integer position) { return new VarSpec(varName, modifier, position); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy