1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.creadur.whisker.fromxml;
20
21 import org.apache.commons.lang3.StringUtils;
22 import org.apache.creadur.whisker.model.*;
23 import org.jdom2.Document;
24 import org.jdom2.Element;
25 import org.jdom2.JDOMException;
26 import org.jdom2.input.SAXBuilder;
27
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.util.*;
31
32
33
34
35 public class JDomBuilder {
36
37 private static final String COPYRIGHT_NOTICE_NAME = "copyright-notice";
38
39
40
41 private static final String LICENSE_ELEMENT_NAME = "license";
42
43
44
45 private static final String PRIMARY_LICENSE_NAME = "primary-license";
46
47 private static final String ORGANISATION_ELEMENT_NAME = "organisation";
48
49 private static final String RESOURCE_ELEMENT_NAME = "resource";
50
51
52
53
54
55
56
57
58
59
60 public Resource resource(Element element) throws UnexpectedElementException {
61 if (RESOURCE_ELEMENT_NAME.equals(element.getName())) {
62 return new Resource(StringUtils.trim(element
63 .getAttributeValue("name")), StringUtils.trim(element
64 .getAttributeValue("notice")), StringUtils.trim(element
65 .getAttributeValue("source")));
66 } else {
67 throw unexpectedElementException(element, RESOURCE_ELEMENT_NAME);
68 }
69 }
70
71
72
73
74
75
76
77
78
79
80 private UnexpectedElementException unexpectedElementException(
81 Element element, final String expectedElement) {
82 return new UnexpectedElementException(expectedElement,
83 element.getName());
84 }
85
86
87
88
89
90
91
92
93
94
95 public Organisation organisation(Element element)
96 throws UnexpectedElementException {
97 if (ORGANISATION_ELEMENT_NAME.equals(element.getName())) {
98 return new Organisation(element.getAttributeValue("id"),
99 element.getAttributeValue("name"),
100 element.getAttributeValue("url"));
101 } else {
102 throw unexpectedElementException(element, ORGANISATION_ELEMENT_NAME);
103 }
104 }
105
106
107
108
109
110
111 @SuppressWarnings("unchecked")
112 public Collection<Resource> collectResources(Element element) {
113 final Collection<Resource> resources = new TreeSet<Resource>();
114 for (Element resourceElement : (List<Element>) element
115 .getChildren("resource")) {
116 resources.add(new JDomBuilder().resource(resourceElement));
117 }
118 return Collections.unmodifiableCollection(resources);
119 }
120
121
122
123
124
125
126
127
128
129
130 public Organisation organisation(final Element element,
131 final Map<String, Organisation> organisationsById)
132 throws MissingIDException {
133 final String id = element.getAttributeValue("id");
134 if (organisationsById.containsKey(id)) {
135 return organisationsById.get(id);
136 } else {
137 throw new MissingIDException(ORGANISATION_ELEMENT_NAME,
138 element.getName(), id);
139 }
140 }
141
142
143
144
145
146
147
148
149
150
151 public ByOrganisation byOrganisation(final Element element,
152 final Organisation organisation) {
153 return new ByOrganisation(organisation, collectResources(element));
154 }
155
156
157
158
159
160
161
162
163
164
165
166
167 public ByOrganisation byOrganisation(final Element byOrganisation,
168 final Map<String, Organisation> organisationsById)
169 throws MissingIDException {
170 return byOrganisation(byOrganisation,
171 organisation(byOrganisation, organisationsById));
172 }
173
174
175
176
177
178
179
180
181
182
183 @SuppressWarnings("unchecked")
184 public SortedSet<ByOrganisation> collectByOrganisations(
185 final Element parent, final Map<String, Organisation> map) {
186 final SortedSet<ByOrganisation> results = new TreeSet<ByOrganisation>();
187 if (parent != null) {
188 for (final Element byOrgElement : (List<Element>) parent
189 .getChildren("by-organisation")) {
190 results.add(byOrganisation(byOrgElement, map));
191 }
192 }
193 return Collections.unmodifiableSortedSet(results);
194 }
195
196
197
198
199
200
201
202
203 public License license(Element element) {
204 final Element text = element.getChild("text");
205 return new License("yes".equalsIgnoreCase(element
206 .getAttributeValue("requires-source")), text == null ? ""
207 : text.getText(), expectedParameters(element),
208 element.getAttributeValue("id"),
209 element.getAttributeValue("url"),
210 element.getAttributeValue("name"));
211 }
212
213 @SuppressWarnings("unchecked")
214 private Collection<String> expectedParameters(final Element element) {
215 final Collection<String> results = new HashSet<String>();
216 final Element templateElement = element.getChild("template");
217 if (templateElement != null) {
218 for (Element parameterNameElement : (List<Element>) templateElement
219 .getChildren("parameter-name")) {
220 results.add(parameterNameElement.getTextTrim());
221 }
222 }
223 return results;
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237 public License license(final Element element,
238 final Map<String, License> licenses) throws MissingIDException {
239 final String id = element.getAttributeValue("id");
240 if (licenses.containsKey(id)) {
241 return licenses.get(id);
242 } else {
243 throw new MissingIDException(LICENSE_ELEMENT_NAME,
244 element.getName(), id);
245 }
246 }
247
248
249
250
251
252
253
254
255
256
257
258
259
260 public WithLicense withLicense(Element element,
261 Map<String, License> licenses,
262 Map<String, Organisation> organisations) throws MissingIDException {
263 return new WithLicense(license(element, licenses),
264 copyrightNotice(element), parameters(element),
265 collectByOrganisations(element, organisations));
266 }
267
268
269
270
271
272
273
274
275 private String copyrightNotice(final Element element) {
276 final String result;
277 final Element copyrightNoticeElement = element
278 .getChild(COPYRIGHT_NOTICE_NAME);
279 if (copyrightNoticeElement == null) {
280 result = null;
281 } else {
282 result = copyrightNoticeElement.getTextTrim();
283 }
284 return result;
285 }
286
287
288
289
290
291
292
293
294
295
296 @SuppressWarnings("unchecked")
297 public Map<String, String> parameters(Element element)
298 throws DuplicateElementException {
299 final Map<String, String> results = new HashMap<String, String>();
300 final Element licenseParametersElement = element
301 .getChild("license-parameters");
302 if (licenseParametersElement != null) {
303 for (Element parameterElement : (List<Element>) licenseParametersElement
304 .getChildren("parameter")) {
305 final String name = parameterElement.getChild("name")
306 .getTextTrim();
307 if (results.containsKey(name)) {
308 throw new DuplicateElementException("Duplicate parameter '"
309 + name + "'");
310 }
311 results.put(name, parameterElement.getChild("value")
312 .getTextTrim());
313 }
314 }
315 return results;
316 }
317
318
319
320
321
322
323
324
325
326
327
328
329 @SuppressWarnings("unchecked")
330 public Collection<WithLicense> withLicenses(Map<String, License> licenses,
331 Map<String, Organisation> organisations, Element parent) {
332 final List<WithLicense> results = new ArrayList<WithLicense>();
333 for (Element withLicenseElement : (List<Element>) parent
334 .getChildren("with-license")) {
335 results.add(new JDomBuilder().withLicense(withLicenseElement,
336 licenses, organisations));
337 }
338 Collections.sort(results);
339 return results;
340 }
341
342
343
344
345
346
347
348
349
350
351 public Collection<ByOrganisation> publicDomain(
352 final Map<String, Organisation> organisations, final Element parent) {
353 return new JDomBuilder().collectByOrganisations(
354 parent.getChild("public-domain"), organisations);
355 }
356
357
358
359
360
361
362
363
364
365
366
367
368 public WithinDirectory withinDirectory(Element element,
369 Map<String, License> licenses,
370 Map<String, Organisation> organisations) {
371 return new WithinDirectory(element.getAttributeValue("dir"),
372 withLicenses(licenses, organisations, element), publicDomain(
373 organisations, element));
374 }
375
376
377
378
379
380
381
382
383 public Map<String, Organisation> mapOrganisations(Document document) {
384 final Map<String, Organisation> organisationsById = new HashMap<String, Organisation>();
385
386 final Element childOrganisations = document.getRootElement().getChild(
387 "organisations");
388 if (childOrganisations != null) {
389 @SuppressWarnings("unchecked")
390 final List<Element> organisations = (List<Element>) childOrganisations
391 .getChildren("organisation");
392 for (final Element element : organisations) {
393 new JDomBuilder().organisation(element).storeIn(
394 organisationsById);
395 }
396 }
397 return Collections.unmodifiableMap(organisationsById);
398 }
399
400
401
402
403
404
405
406
407 public Map<String, License> mapLicenses(Document document) {
408 final Map<String, License> results = new HashMap<String, License>();
409 final Element licensesChild = document.getRootElement().getChild(
410 "licenses");
411 if (licensesChild != null) {
412 @SuppressWarnings("unchecked")
413 final List<Element> children = (List<Element>) licensesChild
414 .getChildren();
415 for (final Element element : children) {
416 new JDomBuilder().license(element).storeIn(results);
417 }
418 }
419 return Collections.unmodifiableMap(results);
420
421 }
422
423
424
425
426
427
428
429
430
431
432 public License primaryLicense(Document document,
433 Map<String, License> licenses) {
434 final String idAttributeValue = getPrimaryLicenseElement(document)
435 .getAttributeValue("id");
436 final License results = licenses.get(idAttributeValue);
437 if (results == null) {
438 throw new MissingIDException(LICENSE_ELEMENT_NAME,
439 PRIMARY_LICENSE_NAME, idAttributeValue);
440 }
441 return results;
442 }
443
444
445
446
447
448
449
450
451 private Element getPrimaryLicenseElement(final Document document) {
452 return document.getRootElement().getChild(PRIMARY_LICENSE_NAME);
453 }
454
455
456
457
458
459
460
461
462 public String primaryCopyrightNotice(final Document document) {
463 final String result;
464 final Element copyrightElement = getPrimaryLicenseElement(document)
465 .getChild(COPYRIGHT_NOTICE_NAME);
466 if (copyrightElement == null) {
467 result = null;
468 } else {
469 result = copyrightElement.getTextTrim();
470 }
471 return result;
472 }
473
474
475
476
477
478
479
480
481 public Map<String, String> mapNotices(Document document) {
482 final Map<String, String> results = new HashMap<String, String>();
483 final Element noticesElement = document.getRootElement().getChild(
484 "notices");
485 if (noticesElement != null) {
486 @SuppressWarnings("unchecked")
487 final List<Element> children = (List<Element>) noticesElement
488 .getChildren();
489 for (final Element element : children) {
490 results.put(element.getAttributeValue("id"),
491 element.getTextTrim());
492 }
493 }
494 return Collections.unmodifiableMap(results);
495
496 }
497
498
499
500
501
502
503
504
505
506 public String primaryNotice(Document document) {
507 final String result;
508 final Element primaryNoticeElement = document.getRootElement()
509 .getChild("primary-notice");
510 if (primaryNoticeElement == null) {
511 result = null;
512 } else {
513 result = primaryNoticeElement.getText()
514 .replace(
515 "${year}",
516 Integer.toString(Calendar.getInstance().get(
517 Calendar.YEAR)));
518 }
519 return result;
520 }
521
522
523
524
525
526
527
528
529 public String primaryOrganisationId(final Document document) {
530 final String result;
531 final Element primaryOrganisationElement = document.getRootElement()
532 .getChild("primary-organisation");
533 if (primaryOrganisationElement == null) {
534 result = null;
535 } else {
536 result = primaryOrganisationElement.getAttributeValue("id");
537 }
538 return result;
539 }
540
541 private WithinDirectory directory(final Element element,
542 final Map<String, License> licenses,
543 final Map<String, Organisation> organisations) {
544 return new JDomBuilder().withinDirectory(element, licenses,
545 organisations);
546 }
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561 public Collection<WithinDirectory> collectContents(final Document document,
562 final Map<String, License> licenses,
563 final Map<String, Organisation> organisations)
564 throws DuplicateElementException {
565 final Collection<WithinDirectory> results = new TreeSet<WithinDirectory>();
566 @SuppressWarnings("unchecked")
567 final List<Element> children = document.getRootElement().getChildren(
568 "within");
569 for (Element element : children) {
570 boolean addedSuccessfully = results.add(directory(element,
571 licenses, organisations));
572
573 if (!addedSuccessfully) {
574 throw new DuplicateElementException("Duplicate parameter '"
575 + element.getAttribute("dir").getValue() + "'");
576 }
577 }
578 return results;
579 }
580
581
582
583
584
585
586
587
588 public Descriptor build(final Document document) {
589 final Map<String, Organisation> organisations = mapOrganisations(document);
590 final Map<String, License> licenses = mapLicenses(document);
591 final Map<String, String> notices = mapNotices(document);
592 final License primaryLicense = primaryLicense(document, licenses);
593 final String primaryCopyrightNotice = primaryCopyrightNotice(document);
594 final String primaryNotice = primaryNotice(document);
595 final String primaryOrganisationId = primaryOrganisationId(document);
596 final Collection<WithinDirectory> contents = collectContents(document,
597 licenses, organisations);
598 return new Descriptor(primaryLicense, primaryCopyrightNotice,
599 primaryOrganisationId, primaryNotice, licenses, notices,
600 organisations, contents);
601 }
602
603 public Descriptor build(final InputStream xmlStream) throws JDOMException,
604 IOException {
605 return build(new SAXBuilder().build(xmlStream));
606 }
607 }