Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ConstraintPrettifier |
|
|
2.3636363636363638;2.364 | ||||
ConstraintPrettifier$1 |
|
|
2.3636363636363638;2.364 | ||||
ConstraintPrettifier$ParameterToken |
|
|
2.3636363636363638;2.364 |
1 | /* |
|
2 | * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH |
|
3 | * |
|
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 | * you may not use this file except in compliance with the License. |
|
6 | * You may obtain a copy of the License at |
|
7 | * |
|
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 | * |
|
10 | * Unless required by applicable law or agreed to in writing, software |
|
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 | * See the License for the specific language governing permissions and |
|
14 | * limitations under the License. |
|
15 | */ |
|
16 | package de.smartics.properties.spi.core.constraint.jsr303; |
|
17 | ||
18 | import java.lang.annotation.Annotation; |
|
19 | import java.util.StringTokenizer; |
|
20 | import java.util.regex.Matcher; |
|
21 | import java.util.regex.Pattern; |
|
22 | ||
23 | /** |
|
24 | * A helper class to make JSR-303 constraints human readable in the context of |
|
25 | * smartics properties. |
|
26 | */ |
|
27 | final class ConstraintPrettifier |
|
28 | { |
|
29 | // ********************************* Fields ********************************* |
|
30 | ||
31 | // --- constants ------------------------------------------------------------ |
|
32 | ||
33 | /** |
|
34 | * The pattern to match constraints in their native, typical |
|
35 | * {@link Annotation#toString()} representation. |
|
36 | */ |
|
37 | 0 | private static final Pattern PATTERN = Pattern |
38 | .compile("@([^(]+)\\(([^)]+)\\)"); |
|
39 | ||
40 | // --- members -------------------------------------------------------------- |
|
41 | ||
42 | /** |
|
43 | * The annotation prettified by this instance. |
|
44 | */ |
|
45 | private final Annotation annotation; |
|
46 | ||
47 | /** |
|
48 | * The prettified instance of the annotation. |
|
49 | */ |
|
50 | private final String pretty; |
|
51 | ||
52 | // ****************************** Initializer ******************************* |
|
53 | ||
54 | // ****************************** Constructors ****************************** |
|
55 | ||
56 | /** |
|
57 | * Default constructor. |
|
58 | * |
|
59 | * @param annotation the annotation prettified by this instance. |
|
60 | * @throws NullPointerException if {@code annotation} is <code>null</code>. |
|
61 | */ |
|
62 | ConstraintPrettifier(final Annotation annotation) throws NullPointerException |
|
63 | 0 | { |
64 | 0 | this.pretty = prettify(annotation); |
65 | 0 | this.annotation = annotation; |
66 | 0 | } |
67 | ||
68 | // ****************************** Inner Classes ***************************** |
|
69 | ||
70 | /** |
|
71 | * A parameter token. |
|
72 | */ |
|
73 | 0 | private static final class ParameterToken |
74 | { |
|
75 | /** |
|
76 | * The name of the token. |
|
77 | */ |
|
78 | private String name; |
|
79 | ||
80 | /** |
|
81 | * Flag to check if the token a name/value pair. |
|
82 | */ |
|
83 | private boolean isNameValue; |
|
84 | ||
85 | /** |
|
86 | * The original token. |
|
87 | */ |
|
88 | private String token; |
|
89 | ||
90 | private boolean isRelevantParameter() |
|
91 | { |
|
92 | 0 | return !("message".equals(name) || "groups".equals(name) || "payload" |
93 | .equals(name)) && !tokenIsEmptyArray(); |
|
94 | } |
|
95 | ||
96 | private boolean tokenIsEmptyArray() |
|
97 | { |
|
98 | 0 | return token.endsWith("=[]"); |
99 | } |
|
100 | ||
101 | private void append(final StringBuilder buffer) |
|
102 | { |
|
103 | 0 | buffer.append(' ').append(token.trim()).append(','); |
104 | 0 | } |
105 | } |
|
106 | ||
107 | // ********************************* Methods ******************************** |
|
108 | ||
109 | // --- init ----------------------------------------------------------------- |
|
110 | ||
111 | // --- get&set -------------------------------------------------------------- |
|
112 | ||
113 | private static String prettify(final Annotation annotation) |
|
114 | throws NullPointerException |
|
115 | { |
|
116 | 0 | final String plain = annotation.toString(); |
117 | ||
118 | 0 | final Matcher matcher = PATTERN.matcher(plain); |
119 | 0 | if (matcher.matches()) |
120 | { |
|
121 | 0 | final StringBuilder buffer = new StringBuilder(128); |
122 | 0 | final String constraint = matcher.group(1); |
123 | 0 | addConstraint(buffer, constraint); |
124 | 0 | final String parameter = matcher.group(2); |
125 | 0 | addParameter(buffer, parameter); |
126 | 0 | return buffer.toString(); |
127 | } |
|
128 | else |
|
129 | { |
|
130 | 0 | return plain; |
131 | } |
|
132 | } |
|
133 | ||
134 | private static void addConstraint(final StringBuilder buffer, |
|
135 | final String constraint) |
|
136 | { |
|
137 | 0 | final int index = constraint.lastIndexOf('.'); |
138 | 0 | if (index > -1 && index < constraint.length() - 1) |
139 | { |
|
140 | 0 | final String shortName = constraint.substring(index + 1); |
141 | 0 | buffer.append(shortName); |
142 | 0 | } |
143 | else |
|
144 | { |
|
145 | 0 | buffer.append(constraint); |
146 | } |
|
147 | 0 | } |
148 | ||
149 | private static void addParameter(final StringBuilder buffer, |
|
150 | final String parameter) |
|
151 | { |
|
152 | 0 | final int initialLength = buffer.length(); |
153 | 0 | final StringTokenizer tokenizer = new StringTokenizer(parameter, ","); |
154 | 0 | while (tokenizer.hasMoreTokens()) |
155 | { |
|
156 | 0 | final ParameterToken token = fetchToken(tokenizer); |
157 | 0 | if (token.isNameValue) |
158 | { |
|
159 | 0 | if (token.isRelevantParameter()) |
160 | { |
|
161 | 0 | token.append(buffer); |
162 | } |
|
163 | } |
|
164 | else |
|
165 | { |
|
166 | 0 | token.append(buffer); |
167 | } |
|
168 | 0 | } |
169 | ||
170 | 0 | if (initialLength < buffer.length()) |
171 | { |
|
172 | 0 | buffer.setCharAt(initialLength, '('); |
173 | 0 | buffer.setCharAt(buffer.length() - 1, ')'); |
174 | } |
|
175 | 0 | } |
176 | ||
177 | private static ParameterToken fetchToken(final StringTokenizer tokenizer) |
|
178 | { |
|
179 | 0 | final ParameterToken result = new ParameterToken(); |
180 | ||
181 | 0 | String token = tokenizer.nextToken(); |
182 | 0 | final int index = token.indexOf('='); |
183 | 0 | result.isNameValue = index != -1; |
184 | 0 | if (result.isNameValue) |
185 | { |
|
186 | 0 | final StringBuilder buffer = new StringBuilder(24); |
187 | 0 | if (token.charAt(index + 1) == '[') |
188 | { |
|
189 | 0 | while (tokenizer.hasMoreTokens() && !token.endsWith("]")) |
190 | { |
|
191 | 0 | buffer.append(token).append(','); |
192 | 0 | token = tokenizer.nextToken(); |
193 | } |
|
194 | 0 | buffer.append(token); |
195 | 0 | result.token = buffer.toString(); |
196 | } |
|
197 | else |
|
198 | { |
|
199 | 0 | result.token = token; |
200 | } |
|
201 | ||
202 | 0 | result.name = result.token.substring(0, index).trim(); |
203 | } |
|
204 | ||
205 | 0 | return result; |
206 | } |
|
207 | ||
208 | /** |
|
209 | * Returns the annotation prettified by this instance. |
|
210 | * |
|
211 | * @return the annotation prettified by this instance. |
|
212 | */ |
|
213 | public Annotation getAnnotation() |
|
214 | { |
|
215 | 0 | return annotation; |
216 | } |
|
217 | ||
218 | /** |
|
219 | * Returns the prettified instance of the annotation. |
|
220 | * |
|
221 | * @return the prettified instance of the annotation. |
|
222 | */ |
|
223 | public String getPretty() |
|
224 | { |
|
225 | 0 | return pretty; |
226 | } |
|
227 | ||
228 | // --- business ------------------------------------------------------------- |
|
229 | ||
230 | // --- object basics -------------------------------------------------------- |
|
231 | ||
232 | @Override |
|
233 | public String toString() |
|
234 | { |
|
235 | 0 | return pretty; |
236 | } |
|
237 | } |