1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.xmlfield.core.internal;
17
18 import static org.apache.commons.lang.StringUtils.isBlank;
19
20 import java.lang.reflect.Method;
21 import java.util.HashMap;
22 import java.util.Map;
23 import java.util.Map.Entry;
24
25 import org.w3c.dom.Node;
26 import org.xmlfield.annotations.Association;
27 import org.xmlfield.annotations.ExplicitCollection;
28 import org.xmlfield.annotations.FieldXPath;
29 import org.xmlfield.annotations.Namespaces;
30 import org.xmlfield.annotations.ResourceXPath;
31 import org.xmlfield.core.XmlField;
32 import org.xmlfield.core.api.XmlFieldNode;
33 import org.xmlfield.core.api.XmlFieldNodeModifier;
34 import org.xmlfield.core.api.XmlFieldObject;
35
36
37
38
39
40
41
42
43 public abstract class XmlFieldUtils {
44
45
46
47
48 private static final String[] METHOD_PREFIXES = { "set", "get", "has",
49 "is", "addTo", "sizeOf", "isNull", "new", "removeFrom" };
50
51
52
53
54
55
56
57
58
59 public static XmlFieldNode createComplexElement(NamespaceMap namespaces,
60 XmlFieldNode contextNode, String elementName, String stringValue,
61 XmlField xf) {
62
63 XmlFieldNode result = contextNode;
64
65 XmlFieldNodeModifier modifier = xf._getModifier();
66
67
68 switch (XPathUtils.getElementType(elementName)) {
69 case XPathUtils.TYPE_ATTRIBUTE:
70 modifier.createAttribute(contextNode, elementName.substring(1),
71 stringValue);
72 break;
73 case XPathUtils.TYPE_TAG:
74
75 result = modifier.createElement(namespaces, contextNode,
76 elementName, stringValue);
77 break;
78
79 case XPathUtils.TYPE_TAG_WITH_ATTRIBUTE:
80
81 String tagName = XPathUtils.getElementName(elementName);
82 result = modifier.createElement(namespaces, contextNode, tagName,
83 stringValue);
84
85
86 Map<String, String> attributes = XPathUtils
87 .getElementSelectorAttributes(elementName);
88 for (String key : attributes.keySet()) {
89 modifier.createAttribute(result, key, attributes.get(key));
90 }
91
92 break;
93 }
94
95 return result;
96
97 }
98
99
100
101
102
103
104
105
106
107
108 public static String emptyTag(String tag, NamespaceMap namespaces) {
109 StringBuilder builder = new StringBuilder("<");
110 builder.append(tag);
111
112 if (namespaces != null) {
113 for (Entry<String, String> entry : namespaces) {
114 builder.append(" xmlns:");
115 builder.append(entry.getKey());
116 builder.append("=\"");
117 builder.append(entry.getValue());
118 builder.append("\"");
119 }
120 }
121 builder.append(" />");
122
123 return builder.toString();
124 }
125
126
127
128
129
130
131
132
133 public static String getElementXPath(String fieldXPath, Class<?> type) {
134 String elementXPath = XPathUtils.getElementXPath(fieldXPath);
135 if (elementXPath == null) {
136 elementXPath = XPathUtils.getElementXPath(getResourceXPath(type)
137 + "/" + fieldXPath);
138 }
139 return elementXPath;
140 }
141
142
143
144
145
146
147
148
149 public static Map<String, Class<?>> getExplicitCollections(
150 final Method method) {
151
152 Map<String, Class<?>> explicitAssociations = new HashMap<String, Class<?>>();
153
154 if (method == null) {
155 return null;
156 }
157
158 final ExplicitCollection explicitCollection = method
159 .getAnnotation(ExplicitCollection.class);
160
161 if (explicitCollection != null) {
162
163 for (int j = 0; j < explicitCollection.value().length; j++) {
164
165
166 if (explicitCollection.value()[j] != null) {
167 Association explicitCollectionAssociation = explicitCollection
168 .value()[j];
169 explicitAssociations.put(
170 explicitCollectionAssociation.xpath(),
171 explicitCollectionAssociation.targetClass());
172 }
173
174 }
175
176 return explicitAssociations;
177 }
178
179 final String methodName = method.getName();
180
181 if (methodName.startsWith("get")) {
182 return explicitAssociations;
183 }
184
185 for (final String prefix : METHOD_PREFIXES) {
186
187 if (methodName.startsWith(prefix)) {
188
189 final String methodSuffix = methodName.substring(prefix
190 .length());
191
192 final Method getterMethod;
193
194 try {
195
196 getterMethod = method.getDeclaringClass().getMethod(
197 "get" + methodSuffix);
198
199 } catch (final NoSuchMethodException e) {
200
201 return null;
202 }
203
204 return getExplicitCollections(getterMethod);
205 }
206 }
207
208 return explicitAssociations;
209 }
210
211
212
213
214
215
216
217
218
219
220
221 public static String getFieldFormat(final Method method) {
222
223 final FieldXPath fieldXPath = getFieldXPathAnnotation(method);
224
225 if (fieldXPath == null) {
226
227 return null;
228 }
229
230 final String format = fieldXPath.format();
231
232 if (isBlank(format)) {
233
234 return null;
235 }
236
237 return format;
238 }
239
240
241
242
243
244
245
246
247
248
249
250 public static String getFieldXPath(final Method method) {
251
252 final FieldXPath fieldXPath = getFieldXPathAnnotation(method);
253
254 if (fieldXPath == null) {
255
256 return null;
257 }
258
259 return fieldXPath.value();
260 }
261
262 private static FieldXPath getFieldXPathAnnotation(final Method method) {
263
264 if (method == null) {
265 return null;
266 }
267
268 final FieldXPath fieldXPath = method.getAnnotation(FieldXPath.class);
269
270 if (fieldXPath != null) {
271
272 return fieldXPath;
273 }
274
275 final String methodName = method.getName();
276
277 if (methodName.startsWith("get")) {
278 return null;
279 }
280
281 for (final String prefix : METHOD_PREFIXES) {
282
283 if (methodName.startsWith(prefix)) {
284
285 final String methodSuffix = methodName.substring(prefix
286 .length());
287
288 final Method getterMethod;
289
290 try {
291
292 getterMethod = method.getDeclaringClass().getMethod(
293 "get" + methodSuffix);
294
295 } catch (final NoSuchMethodException e) {
296
297 return null;
298 }
299
300 return getFieldXPathAnnotation(getterMethod);
301 }
302 }
303
304 return null;
305 }
306
307
308
309
310
311
312
313
314
315 public static Class<?> getFieldXPathType(final Method method) {
316
317 final FieldXPath fieldXPath = getFieldXPathAnnotation(method);
318
319 if (fieldXPath == null) {
320
321 return null;
322 }
323
324 final Class<?> xpathType = fieldXPath.xpathType();
325
326 if (xpathType == null || void.class.equals(xpathType)) {
327
328 return null;
329 }
330
331 return xpathType;
332 }
333
334
335
336
337
338
339
340
341
342 public static NamespaceMap getResourceNamespaces(final Class<?> type) {
343
344 if (type == null) {
345 return null;
346 }
347
348 final Namespaces namespaces = type.getAnnotation(Namespaces.class);
349
350 final Class<?>[] interfaces = type.getInterfaces();
351
352 if (interfaces == null || interfaces.length == 0) {
353
354 return namespaces == null ? null : new NamespaceMap(namespaces);
355 }
356
357 final NamespaceMap nMap = new NamespaceMap(namespaces);
358
359 for (final Class<?> c : interfaces) {
360
361 final NamespaceMap ns = getResourceNamespaces(c);
362
363 nMap.addNamespaces(ns);
364 }
365
366 return nMap.isEmpty() ? null : nMap;
367 }
368
369
370
371
372
373
374
375
376
377 public static String getResourceXPath(final Class<?> type) {
378
379 if (type == null) {
380 return null;
381 }
382
383 final ResourceXPath resourceXPathDeclaration = type
384 .getAnnotation(ResourceXPath.class);
385
386 if (resourceXPathDeclaration == null) {
387
388 return null;
389 }
390
391 return resourceXPathDeclaration.value();
392 }
393
394
395
396
397
398
399
400
401 public static XmlFieldNode getXmlFieldNode(final Object object) {
402 if (object instanceof XmlFieldObject) {
403 return ((XmlFieldObject) object).toNode();
404 }
405 if (object instanceof XmlFieldNode) {
406 return (XmlFieldNode) object;
407 }
408 return null;
409 }
410
411
412
413
414
415
416
417
418
419 public static void remove(final Object item, XmlField xf) {
420 remove(getXmlFieldNode(item), xf);
421 }
422
423
424
425
426
427
428
429 public static void remove(final XmlFieldNode node, XmlField xf) {
430
431 if (node == null) {
432 return;
433 }
434
435 final XmlFieldNode parent = node.getParentNode();
436
437 if (parent != null) {
438 xf._getModifier().removeChild(parent, node);
439 }
440 }
441
442 }