1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.contract.model.util;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.Comparator;
21 import java.util.Enumeration;
22 import java.util.Iterator;
23 import java.util.LinkedHashSet;
24 import java.util.List;
25 import java.util.Set;
26 import java.util.Stack;
27
28 import org.kuali.student.contract.model.MessageStructure;
29 import org.kuali.student.contract.model.Service;
30 import org.kuali.student.contract.model.ServiceContractModel;
31 import org.kuali.student.contract.model.XmlType;
32 import org.kuali.student.contract.writer.HtmlWriter;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36
37
38
39
40 public class HtmlContractWriter {
41
42 private static final Logger log = LoggerFactory.getLogger(HtmlContractWriter.class);
43
44 private HtmlWriter writer;
45 private ServiceContractModel model;
46 private ModelFinder finder;
47 private String directory;
48
49 public HtmlContractWriter(String directory,
50 ServiceContractModel model) {
51 this.writer = new HtmlWriter(directory, "index.html",
52 "Service Contracts Index");
53 this.directory = directory;
54 this.model = model;
55 this.finder = new ModelFinder(this.model);
56 }
57
58 public void write(String projectVersion, String formattedDate) {
59 this.writeIndexPage(projectVersion, formattedDate);
60 for (Service service : model.getServices()) {
61 HtmlContractServiceWriter swriter = new HtmlContractServiceWriter(service,
62 directory,
63 model);
64 swriter.write(projectVersion, formattedDate);
65 }
66 for (XmlType xmlType : model.getXmlTypes()) {
67 HtmlContractMessageStructureWriter msWriter =
68 new HtmlContractMessageStructureWriter(
69 xmlType,
70 directory,
71 model);
72 msWriter.write(projectVersion, formattedDate);
73 }
74 }
75 private static final Comparator<XmlType> XML_TYPE_NAME_COMPARATOR =
76 new Comparator<XmlType>() {
77
78 @Override
79 public int compare(XmlType e1, XmlType e2) {
80 return e1.getName().toLowerCase().compareTo(e2.getName().toLowerCase());
81 }
82 };
83 private static final Comparator<Service> SERVICE_NAME_COMPARATOR =
84 new Comparator<Service>() {
85
86 @Override
87 public int compare(Service e1, Service e2) {
88 return e1.getName().compareTo(e2.getName());
89 }
90 };
91 private static final Comparator<Service> SERVICE_IMPL_NAME_COMPARATOR =
92 new Comparator<Service>() {
93
94 @Override
95 public int compare(Service e1, Service e2) {
96 String x1 = calcArea(e1) + "." + e1.getName();
97 String x2 = calcArea(e2) + "." + e2.getName();
98 return x1.compareTo(x2);
99 }
100 };
101
102 private String getOtherHomeTag () {
103 return "<a href=\"../dictionarydocs/index.html\">Dictionary Docs Home</a>";
104
105 }
106 private void writeIndexPage(String projectVersion, String formattedDate) {
107
108 String otherHome = this.getOtherHomeTag();
109 VersionLinesUtility.writeVersionTag(writer, "<a href=\"index.html\">Home</a>", otherHome, projectVersion, formattedDate);
110
111 writer.writeTag("h1", "Service Contracts");
112
113
114
115 writer.indentPrintln(
116 "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
117 writer.indentPrintln(
118 "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
119 writer.indentPrintln("<b><a name=\"Services\"></a>Services</b>");
120 writer.indentPrintln(
121 "</div><div class=\"panelContent\" style=\"background-color: rgb(255, 255, 255);\">");
122 writer.indentPrintln("<ul>");
123 List<Service> services = new ArrayList<Service>(model.getServices());
124 Collections.sort(services, SERVICE_IMPL_NAME_COMPARATOR);
125 String oldArea = "";
126 for (Service service : services) {
127 String newArea = calcArea(service);
128 if (!newArea.equals(oldArea)) {
129 if (!oldArea.isEmpty()) {
130 writer.indentPrintln("</ul>");
131 writer.decrementIndent();
132 }
133 writer.indentPrintln("<li>" + calcArea(service) + "</li>");
134 writer.incrementIndent();
135 writer.indentPrintln("<ul>");
136 oldArea = newArea;
137 }
138 writer.indentPrint("<li>");
139 writer.print("<a href=\"" + service.getKey() + "Service" + ".html"
140 + "\">" + service.getName() + "</a>");
141 writer.print("</li>");
142 }
143 writer.indentPrintln("</ul>");
144 writer.decrementIndent();
145 writer.indentPrintln("</ul>");
146 writer.indentPrintln("</div>");
147 writer.indentPrintln("</div>");
148
149 this.writeMainOrRootList();
150
151 this.writeAlphabeticalList();
152
153 writer.writeHeaderBodyAndFooterOutToFile();
154
155 }
156
157 private static String calcArea(Service service) {
158 return calcArea(service.getImplProject());
159 }
160
161 private static String calcArea(String implProject) {
162
163 if (implProject.startsWith("org.kuali.student.")) {
164 implProject = implProject.substring("org.kuali.student.".length());
165
166 }
167 if (implProject.startsWith("org.kuali.")) {
168 implProject = implProject.substring("org.kuali.".length());
169 }
170 if (implProject.contains(".api.")) {
171 implProject = implProject.substring(0, implProject.indexOf(".api."));
172 }
173 if (implProject.contains(".api.")) {
174 implProject = implProject.substring(0, implProject.indexOf(".api."));
175 }
176 if (implProject.startsWith("r2.")) {
177 implProject = implProject.substring("r2.".length());
178 }
179 if (implProject.contains(".class1.")) {
180 implProject = implProject.substring(0, implProject.indexOf(".class1.")) +
181 implProject.substring(implProject.indexOf(".class1.") + ".class1".length());
182 }
183 if (implProject.endsWith(".service")) {
184 implProject = implProject.substring(0, implProject.length() - ".service".length());
185 }
186 return implProject;
187 }
188
189 private void writeMainOrRootList() {
190 Stack<String> stack = new Stack();
191 List<XmlType> types = this.getMainMessageStructures();
192 writer.indentPrintln(
193 "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
194 writer.indentPrintln(
195 "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
196 writer.indentPrintln(
197 "<b><a name=\"MessageStructures\"></a> " + types.size() + " Main (root) Message Structures</b>");
198 writer.indentPrintln(
199 "</div><div class=\"panelContent\" style=\"background-color: rgb(255, 255, 255);\">");
200 writer.indentPrintln("<ul>");
201 for (XmlType type : types) {
202 this.writeLink(type);
203 if (!stack.contains(type.getName())) {
204 stack.push(type.getName());
205 this.writeSubStructures(type, stack);
206 stack.pop();
207 }
208 }
209 writer.indentPrintln("</ul>");
210 writer.indentPrintln("</div>");
211 writer.indentPrintln("</div>");
212 }
213
214 private String stripListOffEnd(String name) {
215 if (name.endsWith("List")) {
216 return name.substring(0, name.length() - "List".length());
217 }
218 return name;
219 }
220
221 private boolean shouldWriteSubStructure(XmlType st) {
222 if (!st.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
223 return false;
224 }
225 return true;
226 }
227
228 private void writeSubStructures(XmlType type, Stack<String> stack) {
229 boolean first = true;
230 for (MessageStructure ms : finder.findMessageStructures(type.getName())) {
231 XmlType st = finder.findXmlType(this.stripListOffEnd(ms.getType()));
232 if (st == null) {
233 log.error (ms.getType() + " does not exist in the list of types with parents " + calcParents(stack));
234 continue;
235 }
236 if (!shouldWriteSubStructure (st)) {
237 continue;
238 }
239 if (first) {
240 first = false;
241 writer.indentPrintln("<ul>");
242 }
243 this.writeLink(st);
244 if (!stack.contains(st.getName())) {
245 stack.push(st.getName());
246 this.writeSubStructures(st, stack);
247 stack.pop();
248 }
249 }
250 if (!first) {
251 writer.indentPrintln("</ul>");
252 }
253 }
254
255 private String calcParents(Stack<String> stack) {
256 StringBuilder sb = new StringBuilder();
257 String dot = "";
258 Enumeration<String> en = stack.elements();
259 while (en.hasMoreElements()) {
260 sb.append(dot);
261 dot = ".";
262 sb.append(en.nextElement());
263 }
264 return sb.toString();
265 }
266
267 private void writeLink(XmlType type) {
268 writer.indentPrint("<li>");
269 writer.print("<a href=\"" + type.getName() + ".html"
270 + "\">" + type.getName() + "</a>");
271 writer.print("</li>");
272 }
273
274 private List<XmlType> getMainMessageStructures() {
275 List<XmlType> types = new ArrayList(model.getXmlTypes().size());
276 for (XmlType type : this.getComplexMessageStructures()) {
277 if (isMainMessageStructure(type)) {
278 types.add(type);
279 }
280 }
281 Collections.sort(types, XML_TYPE_NAME_COMPARATOR);
282 return types;
283 }
284
285 private boolean isMainMessageStructure(XmlType xmlType) {
286 if (!HtmlContractMessageStructureWriter.calcOtherXmlTypeUsages(model,
287 xmlType).isEmpty()) {
288 return false;
289 }
290 return true;
291 }
292
293 private List<XmlType> getComplexMessageStructures() {
294 List<XmlType> types = new ArrayList(model.getXmlTypes().size());
295 for (XmlType type : model.getXmlTypes()) {
296 if (type.getPrimitive() == null) {
297 throw new NullPointerException(type.getName()
298 + " has no primitive flag set");
299 }
300 if (type.getPrimitive().equals(XmlType.COMPLEX)) {
301 types.add(type);
302 }
303 }
304 Collections.sort(types, XML_TYPE_NAME_COMPARATOR);
305 return types;
306 }
307
308 private void writeAlphabeticalList() {
309 List<XmlType> types = this.getComplexMessageStructures();
310 writer.indentPrintln(
311 "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
312 writer.indentPrintln(
313 "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
314 writer.indentPrintln(
315 "<b><a name=\"MessageStructures\"></a>All " + types.size() + " Message Structures in Alphabetical Order</b>");
316 writer.indentPrintln(
317 "</div><div class=\"panelContent\" style=\"background-color: rgb(255, 255, 255);\">");
318 writer.indentPrintln("<ul>");
319 for (XmlType type : types) {
320 this.writeLink(type);
321 }
322 writer.indentPrintln("</ul>");
323 writer.indentPrintln("</div>");
324 writer.indentPrintln("</div>");
325 }
326 }