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