15
15
package com .google .api .generator .gapic .composer ;
16
16
17
17
import com .google .api .pathtemplate .PathTemplate ;
18
+ import com .google .common .base .Preconditions ;
18
19
import java .util .ArrayList ;
19
20
import java .util .Arrays ;
20
21
import java .util .List ;
21
22
import java .util .Set ;
22
23
import java .util .stream .Collectors ;
23
24
24
25
public class ResourceNameTokenizer {
25
- private static final String SLASH = "/" ;
26
26
private static final String LEFT_BRACE = "{" ;
27
27
private static final String RIGHT_BRACE = "}" ;
28
+ private static final String SLASH = "/" ;
29
+ private static final String EMPTY = "" ;
30
+
31
+ private static final String EQUALS_WILDCARD = "=*" ;
32
+ private static final String EQUALS_PATH_WILDCARD = "=**" ;
28
33
29
34
static List <List <String >> parseTokenHierarchy (List <String > patterns ) {
30
35
List <String > nonSlashSepStrings = Arrays .asList ("}_{" , "}-{" , "}.{" , "}~{" );
@@ -36,22 +41,38 @@ static List<List<String>> parseTokenHierarchy(List<String> patterns) {
36
41
String [] patternTokens = pattern .split (SLASH );
37
42
for (String patternToken : patternTokens ) {
38
43
if (patternToken .startsWith (LEFT_BRACE ) && patternToken .endsWith (RIGHT_BRACE )) {
39
- String processedPatternToken = patternToken ;
44
+ String processedPatternToken =
45
+ // Replacement order matters - ensure the first is not a subcomponent of the second.
46
+ patternToken .replace (EQUALS_PATH_WILDCARD , EMPTY ).replace (EQUALS_WILDCARD , EMPTY );
40
47
41
48
// Handle non-slash separators.
42
49
if (nonSlashSepStrings .stream ().anyMatch (s -> patternToken .contains (s ))) {
43
50
for (String str : nonSlashSepStrings ) {
44
51
processedPatternToken = processedPatternToken .replace (str , "_" );
45
52
}
46
53
} else {
54
+ final int processedPatternTokenLength = processedPatternToken .length ();
47
55
// Handles wildcards.
48
- processedPatternToken =
56
+ List < String > candidateVars =
49
57
vars .stream ()
50
- .filter (v -> patternToken .contains (v ))
51
- .collect (Collectors .toList ())
52
- .get (0 );
58
+ // Check that the token size is within ~3 of the var, to avoid mismatching on
59
+ // variables with same-named subcomponents.
60
+ // Otherwise, "customer_client_link" will match with "customer".
61
+ .filter (
62
+ v ->
63
+ patternToken .contains (v )
64
+ // Accounting for braces.
65
+ && processedPatternTokenLength - v .length () < 3 )
66
+ .collect (Collectors .toList ());
67
+ Preconditions .checkState (
68
+ !candidateVars .isEmpty (),
69
+ String .format (
70
+ "No variable candidates found for token %s in pattern %s" ,
71
+ processedPatternToken , pattern ));
72
+ processedPatternToken = candidateVars .get (0 );
53
73
}
54
- hierarchy .add (processedPatternToken .replace ("{" , "" ).replace ("}" , "" ));
74
+ hierarchy .add (
75
+ processedPatternToken .replace (LEFT_BRACE , EMPTY ).replace (RIGHT_BRACE , EMPTY ));
55
76
}
56
77
}
57
78
tokenHierachies .add (hierarchy );
0 commit comments