Skip to content
This repository was archived by the owner on Sep 27, 2023. It is now read-only.

Commit 955b8a7

Browse files
authored
fix: enable complex resource ids in instantiate() (#159)
1 parent 39612f1 commit 955b8a7

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

src/main/java/com/google/api/pathtemplate/PathTemplate.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,11 @@ private static Segment create(SegmentKind kind, String value) {
200200
return new AutoValue_PathTemplate_Segment(kind, value, "");
201201
}
202202

203+
/** Creates a segment of given kind, value, and complex separator. */
204+
private static Segment create(SegmentKind kind, String value, String complexSeparator) {
205+
return new AutoValue_PathTemplate_Segment(kind, value, complexSeparator);
206+
}
207+
203208
private static Segment wildcardCreate(String complexSeparator) {
204209
return new AutoValue_PathTemplate_Segment(
205210
SegmentKind.WILDCARD,
@@ -737,10 +742,13 @@ private String instantiate(Map<String, String> values, boolean allowPartial) {
737742
boolean continueLast = true; // Whether to not append separator
738743
boolean skip = false; // Whether we are substituting a binding and segments shall be skipped.
739744
ListIterator<Segment> iterator = segments.listIterator();
745+
String prevSeparator = "";
740746
while (iterator.hasNext()) {
741747
Segment seg = iterator.next();
742748
if (!skip && !continueLast) {
743-
result.append(seg.separator());
749+
String separator = prevSeparator.isEmpty() ? seg.separator() : prevSeparator;
750+
result.append(separator);
751+
prevSeparator = seg.complexSeparator().isEmpty() ? seg.separator() : seg.complexSeparator();
744752
}
745753
continueLast = false;
746754
switch (seg.kind()) {
@@ -1066,7 +1074,7 @@ private static List<Segment> parseComplexResourceId(String seg) {
10661074
currIteratorIndex < separatorIndices.size()
10671075
? separatorIndices.get(currIteratorIndex)
10681076
: "";
1069-
segments.add(Segment.create(SegmentKind.BINDING, subVarName));
1077+
segments.add(Segment.create(SegmentKind.BINDING, subVarName, complexDelimiter));
10701078
segments.add(Segment.wildcardCreate(complexDelimiter));
10711079
segments.add(Segment.END_BINDING);
10721080
subVarName = null;

src/test/java/com/google/api/pathtemplate/PathTemplateTest.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.Arrays;
3838
import java.util.List;
3939
import java.util.Map;
40+
import java.util.Set;
4041
import org.junit.Rule;
4142
import org.junit.Test;
4243
import org.junit.rules.ExpectedException;
@@ -377,6 +378,26 @@ public void complexResourceIdInParent() {
377378
Truth.assertThat(match.get("cell2")).isEqualTo("broomba");
378379
}
379380

381+
@Test
382+
public void complexResourcePathTemplateVariables() {
383+
String pattern =
384+
"projects/{foo}_{bar}/zones/{zone_a}-{zone_b}_{zone_c}/machines/{cell1}.{cell2}";
385+
PathTemplate template = PathTemplate.create(pattern);
386+
Set<String> variables = template.vars();
387+
Truth.assertThat(variables)
388+
.containsExactly("foo", "bar", "zone_a", "zone_b", "zone_c", "cell1", "cell2");
389+
390+
pattern = "projects/{foo}_{bar}/zones/*";
391+
template = PathTemplate.create(pattern);
392+
Map<String, String> match =
393+
template.match("https://www.googleapis.com/compute/v1/projects/foo1_bar2/zones/azone");
394+
Truth.assertThat(match).isNotNull();
395+
Truth.assertThat(match.get("foo")).isEqualTo("foo1");
396+
Truth.assertThat(match.get("bar")).isEqualTo("bar2");
397+
variables = template.vars();
398+
System.out.println("DEL: vars: " + variables);
399+
}
400+
380401
@Test
381402
public void complexResourceBasicInvalidIds() {
382403
thrown.expect(ValidationException.class);
@@ -575,6 +596,57 @@ public void instantiateWithUnusualCharactersNoEncoding() {
575596
Truth.assertThat(instance).isEqualTo("bar/asdf:;`~,.<>[]!@#$%^&*()");
576597
}
577598

599+
@Test
600+
public void instantiateWithComplexResourceId_basic() {
601+
PathTemplate template = PathTemplate.create("projects/{project}/zones/{zone_a}~{zone_b}");
602+
String instance =
603+
template.instantiate("project", "a/b/c", "zone_a", "apple", "zone_b", "baseball");
604+
Truth.assertThat(instance).isEqualTo("projects/a%2Fb%2Fc/zones/apple~baseball");
605+
}
606+
607+
@Test
608+
public void instantiateWithComplexResourceId_mixedSeparators() {
609+
PathTemplate template =
610+
PathTemplate.create(
611+
"projects/{project}/zones/{zone_a}~{zone_b}.{zone_c}-{zone_d}~{zone_e}");
612+
String instance =
613+
template.instantiate(
614+
"project",
615+
"a/b/c",
616+
"zone_a",
617+
"apple",
618+
"zone_b",
619+
"baseball/basketball",
620+
"zone_c",
621+
"cat/kitty",
622+
"zone_d",
623+
"dog/hound",
624+
"zone_e",
625+
"12345");
626+
Truth.assertThat(instance)
627+
.isEqualTo(
628+
"projects/a%2Fb%2Fc/zones/apple~baseball%2Fbasketball.cat%2Fkitty-dog%2Fhound~12345");
629+
}
630+
631+
@Test
632+
public void instantiateWithComplexResourceId_mixedSeparatorsInParent() {
633+
PathTemplate template =
634+
PathTemplate.create("projects/{project_a}~{project_b}.{project_c}/zones/{zone_a}~{zone_b}");
635+
String instance =
636+
template.instantiate(
637+
"project_a",
638+
"a/b/c",
639+
"project_b",
640+
"foo",
641+
"project_c",
642+
"bar",
643+
"zone_a",
644+
"apple",
645+
"zone_b",
646+
"baseball");
647+
Truth.assertThat(instance).isEqualTo("projects/a%2Fb%2Fc~foo.bar/zones/apple~baseball");
648+
}
649+
578650
// Other
579651
// =====
580652

0 commit comments

Comments
 (0)