1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.scripting.velocity;
17
18 import java.io.IOException;
19 import java.io.StringWriter;
20 import java.io.Writer;
21 import java.util.Locale;
22
23 import org.apache.velocity.context.InternalContextAdapter;
24 import org.apache.velocity.runtime.directive.Directive;
25 import org.apache.velocity.runtime.parser.node.ASTBlock;
26 import org.apache.velocity.runtime.parser.node.Node;
27
28 public class TrimDirective extends Directive {
29
30 @Override
31 public String getName() {
32 return "trim";
33 }
34
35 @Override
36 public final int getType() {
37 return BLOCK;
38 }
39
40 @Override
41 public final boolean render(InternalContextAdapter ica, Writer writer, Node node) throws IOException {
42 Params p = getParams(ica, node);
43 if (p == null) {
44 return false;
45 }
46 return render(p, writer);
47 }
48
49 public boolean render(final Params params, final Writer writer) throws IOException {
50 int leftIndex = 0;
51 int rightIndex = params.maxBody;
52 if (rightIndex == 0) {
53 return false;
54 }
55 if (!params.prefixOverrides.isEmpty()) {
56 final String LEFT = params.body
57 .substring(0, params.maxPrefixLength < params.maxBody ? params.maxPrefixLength : params.maxBody)
58 .toUpperCase(Locale.ENGLISH);
59 FastLinkedList<String>.Node n = params.prefixOverrides.start();
60 while (n != null) {
61 if (LEFT.startsWith(n.data)) {
62 leftIndex = n.data.length();
63 break;
64 }
65 n = n.next;
66 }
67 }
68 if (!params.suffixOverrides.isEmpty()) {
69 final String RIGHT = params.body
70 .substring(rightIndex > params.maxSuffixLength ? rightIndex - params.maxSuffixLength : 0)
71 .toUpperCase(Locale.ENGLISH);
72 FastLinkedList<String>.Node n = params.suffixOverrides.start();
73 while (n != null) {
74 if (RIGHT.endsWith(n.data)) {
75 rightIndex = rightIndex - n.data.length();
76 break;
77 }
78 n = n.next;
79 }
80 }
81 if (rightIndex > leftIndex) {
82 String content = params.body.substring(leftIndex, rightIndex).trim();
83 if (!"".equals(content)) {
84 writer.append(params.prefix).append(' ');
85 writer.append(params.body, leftIndex, rightIndex).append(' ');
86 writer.append(params.suffix);
87 }
88 }
89 return true;
90 }
91
92 protected static final class Params {
93
94 String prefix = "";
95
96 String suffix = "";
97
98 FastLinkedList<String> prefixOverrides = new FastLinkedList<>();
99
100 FastLinkedList<String> suffixOverrides = new FastLinkedList<>();
101
102 String body = "";
103
104 int maxPrefixLength = 0;
105
106 int maxSuffixLength = 0;
107
108 int maxBody = 0;
109
110 public String getBody() {
111 return this.body;
112 }
113
114 public void setBody(String value) {
115 if (value == null) {
116 this.body = "";
117 } else {
118 this.body = value.trim();
119 }
120 this.maxBody = this.body.length();
121 }
122
123 public String getPrefix() {
124 return this.prefix;
125 }
126
127 public void setPrefix(String value) {
128 this.prefix = value;
129 }
130
131 public FastLinkedList<String> getPrefixOverrides() {
132 return this.prefixOverrides;
133 }
134
135 public void setPrefixOverrides(String list) {
136 this.maxPrefixLength = fromStringList(list, '|', this.prefixOverrides);
137 }
138
139 public FastLinkedList<String> getSuffixOverrides() {
140 return this.suffixOverrides;
141 }
142
143 public void setSuffixOverrides(String list) {
144 this.maxSuffixLength = fromStringList(list, '|', this.suffixOverrides);
145 }
146
147 public String getSuffix() {
148 return this.suffix;
149 }
150
151 public void setSuffix(String value) {
152 this.suffix = value;
153 }
154
155 }
156
157 protected Params getParams(final InternalContextAdapter context, final Node node) throws IOException {
158 final Params params = new Params();
159 final int nodes = node.jjtGetNumChildren();
160 for (int i = 0; i < nodes; i++) {
161 Node child = node.jjtGetChild(i);
162 if (child != null) {
163 if (!(child instanceof ASTBlock)) {
164 if (i == 0) {
165 params.setPrefix(String.valueOf(child.value(context)));
166 } else if (i == 1) {
167 params.setPrefixOverrides(String.valueOf(child.value(context)).toUpperCase(Locale.ENGLISH));
168 } else if (i == 2) {
169 params.setSuffix(String.valueOf(child.value(context)));
170 } else if (i == 3) {
171 params.setSuffixOverrides(String.valueOf(child.value(context)).toUpperCase(Locale.ENGLISH));
172 } else {
173 break;
174 }
175 } else {
176 StringWriter blockContent = new StringWriter();
177 child.render(context, blockContent);
178 params.setBody(blockContent.toString().trim());
179 break;
180 }
181 }
182 }
183 return params;
184 }
185
186 static int fromStringList(final String list, final char sep, final FastLinkedList<String> fll) {
187 int max = 0;
188 if (list != null) {
189 final int n = list.length();
190 int i = 0;
191 while (i < n) {
192 int r = list.indexOf(sep, i);
193 if (i < r) {
194 fll.add(list.substring(i, r));
195 int len = r - i;
196 if (len > max) {
197 max = len;
198 }
199 i = r + 1;
200 } else {
201 break;
202 }
203 }
204 if (i < n) {
205 fll.add(list.substring(i));
206 int len = n - i;
207 if (len > max) {
208 max = len;
209 }
210 }
211 }
212 return max;
213 }
214
215 }