1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package gov.nist.secauto.metaschema.schemagen.xml.datatype;
28
29 import gov.nist.secauto.metaschema.schemagen.datatype.IDatatypeContent;
30 import gov.nist.secauto.metaschema.schemagen.datatype.IDatatypeProvider;
31
32 import org.codehaus.stax2.XMLStreamWriter2;
33 import org.jdom2.Element;
34 import org.jdom2.JDOMException;
35
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.util.Collections;
39 import java.util.LinkedHashSet;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Set;
43
44 import javax.xml.stream.XMLStreamException;
45
46 import edu.umd.cs.findbugs.annotations.NonNull;
47 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
48
49 public abstract class AbstractXmlDatatypeProvider implements IDatatypeProvider {
50 private Map<String, IDatatypeContent> datatypes;
51
52 protected abstract InputStream getSchemaResource();
53
54 private void initSchema() {
55 synchronized (this) {
56 if (datatypes == null) {
57 try (InputStream is = getSchemaResource()) {
58 assert is != null;
59 JDom2XmlSchemaLoader loader = new JDom2XmlSchemaLoader(is);
60
61 List<Element> elements = queryElements(loader);
62
63 datatypes = Collections.unmodifiableMap(handleResults(elements));
64 } catch (JDOMException | IOException ex) {
65 throw new IllegalStateException(ex);
66 }
67 }
68 }
69 }
70
71 @NonNull
72 protected abstract List<Element> queryElements(JDom2XmlSchemaLoader loader);
73
74 @NonNull
75 protected abstract Map<String, IDatatypeContent> handleResults(@NonNull List<Element> items);
76
77 @Override
78 @SuppressFBWarnings({ "IS2_INCONSISTENT_SYNC", "MT_CORRECTNESS", "EI_EXPOSE_REP" })
79 public Map<String, IDatatypeContent> getDatatypes() {
80 initSchema();
81 assert datatypes != null;
82 return datatypes;
83 }
84
85 @Override
86 public Set<String> generateDatatypes(Set<String> requiredTypes, @NonNull XMLStreamWriter2 writer)
87 throws XMLStreamException {
88 Map<String, IDatatypeContent> datatypes = getDatatypes();
89
90 Set<String> providedDatatypes = new LinkedHashSet<>();
91 for (IDatatypeContent datatype : datatypes.values()) {
92 String type = datatype.getTypeName();
93 if (requiredTypes.contains(type)) {
94 providedDatatypes.add(type);
95 providedDatatypes.addAll(datatype.getDependencies());
96 }
97 }
98
99 for (IDatatypeContent datatype : datatypes.values()) {
100 String type = datatype.getTypeName();
101 if (providedDatatypes.contains(type)) {
102 datatype.write(writer);
103 }
104 }
105 return providedDatatypes;
106 }
107
108 }