1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.guice.datasource.helper;
17
18 import com.google.inject.Injector;
19 import com.google.inject.util.Providers;
20
21 import jakarta.inject.Inject;
22 import jakarta.inject.Provider;
23
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.StringTokenizer;
27
28 public final class JdbcUrlAntFormatter implements Provider<String> {
29
30 private static final String VAR_BEGIN = "$";
31
32 private static final String PIPE_SEPARATOR = "|";
33
34 private final List<Provider<String>> appenders = new ArrayList<Provider<String>>();
35
36 private final List<KeyResolver> resolvers = new ArrayList<KeyResolver>();
37
38
39
40
41
42
43
44 public JdbcUrlAntFormatter(final String pattern) {
45 initializeAppender(pattern);
46 }
47
48
49
50
51
52
53
54 private void initializeAppender(String pattern) {
55 int previousIndex = 0;
56 int currentIndex;
57 while ((currentIndex = pattern.indexOf(VAR_BEGIN, previousIndex)) >= 0) {
58 processPatternSubstring(pattern, previousIndex, currentIndex);
59 previousIndex = updatePrevPosition(pattern, currentIndex);
60 }
61 appendRemainingPatternSubstring(pattern, previousIndex);
62 }
63
64
65 private void processPatternSubstring(String pattern, int previousIndex, int currentIndex) {
66 if (currentIndex > 0) {
67 appenders.add(Providers.of(pattern.substring(previousIndex, currentIndex)));
68 }
69
70 if (currentIndex == pattern.length() - 1) {
71 appenders.add(Providers.of(VAR_BEGIN));
72 } else if (pattern.charAt(currentIndex + 1) != '{') {
73 handleNonCurlyBracePattern(pattern, currentIndex);
74 } else {
75 handleCurlyBracePattern(pattern, currentIndex);
76 }
77 }
78
79
80 private void handleNonCurlyBracePattern(String pattern, int currentIndex) {
81 if (pattern.charAt(currentIndex + 1) == '$') {
82 appenders.add(Providers.of(VAR_BEGIN));
83 } else {
84 appenders.add(Providers.of(pattern.substring(currentIndex, currentIndex + 2)));
85 }
86 }
87
88
89 private void handleCurlyBracePattern(String pattern, int currentIndex) {
90 int endName = pattern.indexOf('}', currentIndex);
91 if (endName < 0) {
92 throw new IllegalArgumentException("Syntax error in property: " + pattern);
93 }
94 processKeyResolver(pattern, currentIndex, endName);
95 }
96
97
98 private void processKeyResolver(String pattern, int startPos, int endPos) {
99 StringTokenizer keyTokenizer = new StringTokenizer(pattern.substring(startPos + 2, endPos), PIPE_SEPARATOR);
100 String key = keyTokenizer.nextToken();
101 String defaultValue = keyTokenizer.hasMoreTokens() ? keyTokenizer.nextToken() : null;
102 KeyResolver resolver = new KeyResolver(key, defaultValue);
103 appenders.add(resolver);
104 resolvers.add(resolver);
105 }
106
107
108 private int updatePrevPosition(String pattern, int currentIndex) {
109 if (pattern.charAt(currentIndex + 1) == '{') {
110 return pattern.indexOf('}', currentIndex) + 1;
111 } else {
112 return currentIndex + (pattern.charAt(currentIndex + 1) == '$' ? 2 : 1);
113 }
114 }
115
116
117 private void appendRemainingPatternSubstring(String pattern, int previousIndex) {
118 if (previousIndex < pattern.length()) {
119 appenders.add(Providers.of(pattern.substring(previousIndex)));
120 }
121 }
122
123
124
125
126
127
128
129 @Inject
130 public void setInjector(Injector injector) {
131 for (KeyResolver resolver : resolvers) {
132 resolver.setInjector(injector);
133 }
134 }
135
136 @Override
137 public String get() {
138 StringBuilder buffer = new StringBuilder();
139 for (Provider<String> appender : appenders) {
140 buffer.append(appender.get());
141 }
142 return buffer.toString();
143 }
144
145 @Override
146 public String toString() {
147 return appenders.toString();
148 }
149
150 }