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.impl;
28
29 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
30 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
31 import gov.nist.secauto.metaschema.core.model.IDefinition;
32 import gov.nist.secauto.metaschema.core.model.IModelElement;
33 import gov.nist.secauto.metaschema.core.model.INamedInstance;
34 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
35 import gov.nist.secauto.metaschema.schemagen.SchemaGenerationException;
36 import gov.nist.secauto.metaschema.schemagen.xml.XmlSchemaGenerator;
37
38 import java.util.ArrayList;
39 import java.util.List;
40
41 import javax.xml.stream.XMLStreamException;
42
43 import edu.umd.cs.findbugs.annotations.NonNull;
44 import edu.umd.cs.findbugs.annotations.Nullable;
45
46 public final class DocumentationGenerator {
47
48 private final @Nullable String formalName;
49 private final @Nullable MarkupLine description;
50 private final @NonNull List<MarkupMultiline> remarks;
51 private final @NonNull IModelElement modelElement;
52
53 private DocumentationGenerator(@NonNull IDefinition definition) {
54 this.formalName = definition.getEffectiveFormalName();
55 this.description = definition.getEffectiveDescription();
56
57 MarkupMultiline remarks = definition.getRemarks();
58 this.remarks = remarks == null ? CollectionUtil.emptyList() : CollectionUtil.singletonList(remarks);
59
60 this.modelElement = definition;
61 }
62
63 private DocumentationGenerator(@NonNull INamedInstance instance) {
64 this.formalName = instance.getEffectiveFormalName();
65 this.description = instance.getEffectiveDescription();
66
67 List<MarkupMultiline> remarks = new ArrayList<>(2);
68 MarkupMultiline remark = instance.getRemarks();
69 if (remark != null) {
70 remarks.add(remark);
71 }
72
73 remark = instance.getDefinition().getRemarks();
74 if (remark != null) {
75 remarks.add(remark);
76 }
77
78 this.remarks = CollectionUtil.listOrEmpty(remarks);
79
80 this.modelElement = instance;
81 }
82
83 @Nullable
84 public String getFormalName() {
85 return formalName;
86 }
87
88 @Nullable
89 public MarkupLine getDescription() {
90 return description;
91 }
92
93 @NonNull
94 public List<MarkupMultiline> getRemarks() {
95 return remarks;
96 }
97
98 @NonNull
99 public IModelElement getModelElement() {
100 return modelElement;
101 }
102
103 private void generate(@NonNull XmlGenerationState state) {
104 String formalName = getFormalName();
105 MarkupLine description = getDescription();
106 List<MarkupMultiline> remarks = getRemarks();
107
108 if (formalName != null || description != null || !remarks.isEmpty()) {
109 generateDocumentation(formalName, description, remarks, state.getNS(getModelElement()), state);
110 }
111 }
112
113 public static void generateDocumentation(
114 @NonNull IDefinition definition,
115 @NonNull XmlGenerationState state) {
116 new DocumentationGenerator(definition).generate(state);
117 }
118
119 public static void generateDocumentation(
120 @NonNull INamedInstance instance,
121 @NonNull XmlGenerationState state) {
122 new DocumentationGenerator(instance).generate(state);
123 }
124
125 public static void generateDocumentation(
126 @Nullable String formalName,
127 @Nullable MarkupLine description,
128 @NonNull List<MarkupMultiline> remarks,
129 @NonNull String xmlNS, @NonNull XmlGenerationState state) {
130
131 try {
132 state.writeStartElement(XmlSchemaGenerator.PREFIX_XML_SCHEMA, "annotation", XmlSchemaGenerator.NS_XML_SCHEMA);
133 if (formalName != null || description != null) {
134 state.writeStartElement(XmlSchemaGenerator.PREFIX_XML_SCHEMA, "appinfo", XmlSchemaGenerator.NS_XML_SCHEMA);
135
136 if (formalName != null) {
137 state.writeStartElement(xmlNS, "formal-name");
138 state.writeCharacters(formalName);
139 state.writeEndElement();
140 }
141
142 if (description != null) {
143 state.writeStartElement(xmlNS, "description");
144 description.writeXHtml(xmlNS, state.getXMLStreamWriter());
145 state.writeEndElement();
146 }
147
148 state.writeEndElement();
149 }
150
151 state.writeStartElement(XmlSchemaGenerator.PREFIX_XML_SCHEMA, "documentation", XmlSchemaGenerator.NS_XML_SCHEMA);
152 state.writeNamespace("", XmlSchemaGenerator.NS_XHTML);
153
154 if (description != null) {
155
156 state.writeStartElement(XmlSchemaGenerator.NS_XHTML, "p");
157
158 if (formalName != null) {
159 state.writeStartElement(XmlSchemaGenerator.NS_XHTML, "b");
160 state.writeCharacters(formalName);
161 state.writeEndElement();
162 state.writeCharacters(": ");
163 }
164
165 description.writeXHtml(XmlSchemaGenerator.NS_XHTML, state.getXMLStreamWriter());
166 state.writeEndElement();
167 }
168
169 for (MarkupMultiline remark : remarks) {
170 remark.writeXHtml(XmlSchemaGenerator.NS_XHTML, state.getXMLStreamWriter());
171 }
172
173 state.writeEndElement();
174 state.writeEndElement();
175 } catch (XMLStreamException ex) {
176 throw new SchemaGenerationException(ex);
177 }
178 }
179 }