001 /*
002 * Copyright 2011 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.osedu.org/licenses/ECL-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.student.contract.model.util;
017
018 import java.util.Date;
019 import java.util.LinkedHashSet;
020 import java.util.List;
021 import java.util.Set;
022
023 import org.kuali.student.contract.model.Service;
024 import org.kuali.student.contract.model.ServiceContractModel;
025 import org.kuali.student.contract.model.ServiceMethod;
026 import org.kuali.student.contract.model.ServiceMethodError;
027 import org.kuali.student.contract.model.ServiceMethodParameter;
028 import org.kuali.student.contract.model.XmlType;
029 import org.kuali.student.contract.writer.HtmlWriter;
030
031 /**
032 *
033 * @author nwright
034 */
035 public class HtmlContractServiceWriter {
036
037 private Service service;
038 private HtmlWriter writer;
039 private ServiceContractModel model;
040 private ModelFinder finder;
041
042 public HtmlContractServiceWriter(Service service, String directory,
043 ServiceContractModel model) {
044 this.service = service;
045 this.writer = new HtmlWriter(directory, service.getKey() + "Service" + ".html",
046 service.getName());
047 this.model = model;
048 this.finder = new ModelFinder(this.model);
049 }
050
051 public void write(String projectVersion, String formattedDate) {
052 this.writeStyleSheet();
053
054
055 VersionLinesUtility.writeVersionTag(writer, "<a href=\"index.html\">home</a>", "", projectVersion, formattedDate);
056
057 writer.writeTag("h1", service.getName());
058
059 writer.indentPrintln("<table id=\"serviceMetaTable\">");
060 writer.indentPrintln("<tr>");
061 writer.writeTag("th", "class=h", "Key");
062 writer.writeTag("td", "id=serviceName colspan=2", service.getKey());
063 writer.indentPrintln("</tr>");
064
065 writer.indentPrintln("<tr>");
066 writer.writeTag("th", "class=h", "Version");
067 writer.writeTag("td", "id=serviceVersion colspan=2", service.getVersion());
068 writer.indentPrintln("</tr>");
069 writer.indentPrintln("<tr>");
070 writer.writeTag("th", "class=h", "Included Services");
071
072 writer.writeTag("td", "id=serviceVersion colspan=2", calcIncludedServices(
073 service.getIncludedServices()));
074 writer.indentPrintln("</tr>");
075
076 writer.indentPrintln("<tr>");
077 writer.writeTag("th", "class=h", "Java Package");
078
079 writer.writeTag("td", "id=serviceVersion colspan=2", service.getImplProject());
080 writer.indentPrintln("</tr>");
081
082
083 writer.indentPrintln("</table>");
084
085 // writer.indentPrintln ("<div class=\"panel\" style=\"border-width: 1px;\">");
086 // writer.indentPrintln ("<div class=\"panelHeader\" style=\"border-bottom-width: 1px;\">");
087 writer.indentPrintln("<p>");
088 // writer.indentPrintln("<table id=\"serviceMetaTable\">");
089 // writer.indentPrintln("<tr>");
090 // writer.indentPrintln("<td>");
091 writer.indentPrintln(
092 "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
093 writer.indentPrintln(
094 "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
095 writer.indentPrintln(this.addHTMLBreaks(service.getComments()));
096 writer.indentPrintln("</div>");
097 writer.indentPrintln("</div>");
098 // writer.indentPrintln("</td>");
099 // writer.indentPrintln("</tr>");
100 // writer.indentPrintln("</table>");
101
102 // writer.indentPrintln ("</div>");
103 // writer.indentPrintln ("</div>");
104
105 writer.indentPrintln("<p>");
106 writer.indentPrintln(
107 "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
108 writer.indentPrintln(
109 "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
110 writer.indentPrintln("<b><a name=\"ListOfOperations\"></a>Operations</b>");
111 writer.indentPrintln(
112 "</div><div class=\"panelContent\" style=\"background-color: rgb(255, 255, 255);\">");
113 writer.indentPrintln("<ul>");
114 for (ServiceMethod method : finder.getServiceMethodsInService(
115 service.getKey())) {
116 writer.indentPrint("<li>");
117 writer.print("<a href=\"#" + method.getService() + "-" + method.getName()
118 + "\">" + method.getName() + "</a>");
119 writer.print("</li>");
120 }
121 writer.indentPrintln("</ul>");
122 writer.indentPrintln("</div>");
123 writer.indentPrintln("</div>");
124
125 // now write out the root message structures
126 writer.indentPrintln(
127 "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
128 writer.indentPrintln(
129 "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
130 writer.indentPrintln(
131 "<b><a name=\"MainMessageStructures\"></a>Main Message Structures</b>");
132 writer.indentPrintln(
133 "</div><div class=\"panelContent\" style=\"background-color: rgb(255, 255, 255);\">");
134
135 writer.indentPrintln("<ul>");
136 for (XmlType type : this.calcMainMessageStructures()) {
137 writer.indentPrint("<li>");
138 writer.print("<a href=\"" + type.getName() + ".html"
139 + "\">" + type.getName() + "</a>");
140 writer.print("</li>");
141 }
142 writer.indentPrintln("</ul>");
143
144
145 for (ServiceMethod method : finder.getServiceMethodsInService(
146 service.getKey())) {
147 this.writeMethod(method);
148 }
149
150 writer.writeHeaderBodyAndFooterOutToFile();
151
152 writer.getOut().close();
153 }
154
155 private String calcIncludedServices(List<String> includedServices) {
156 if (includedServices == null) {
157 return " ";
158 }
159 if (includedServices.isEmpty()) {
160 return " ";
161 }
162 StringBuilder bldr = new StringBuilder();
163 String comma = "";
164 for (String includedService : includedServices) {
165 bldr.append(comma);
166 comma = ", ";
167 bldr.append("<a href=\"" + includedService + ".html"
168 + "\">" + includedService + "</a>");
169 }
170 return bldr.toString();
171 }
172
173 private Set<XmlType> calcMainMessageStructures() {
174 return calcMainMessageStructures(model, service.getKey());
175 }
176
177 public static Set<XmlType> calcMainMessageStructures(ServiceContractModel mdl,
178 String serviceOptionaFilter) {
179 ModelFinder fndr = new ModelFinder(mdl);
180 Set<XmlType> types = new LinkedHashSet();
181 for (ServiceMethod method : mdl.getServiceMethods()) {
182 if (serviceOptionaFilter != null) {
183 if (!method.getService().equalsIgnoreCase(serviceOptionaFilter)) {
184 continue;
185 }
186 }
187 XmlType type = fndr.findXmlType(stripListFromType(method.getReturnValue().getType()));
188 if (type != null) {
189 if (type.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
190 types.add(type);
191 }
192 }
193
194 for (ServiceMethodParameter param : method.getParameters()) {
195 type = fndr.findXmlType(stripListFromType(param.getType()));
196 if (type != null) {
197 if (type.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
198 types.add(type);
199 }
200 }
201 break;
202 }
203 }
204 return types;
205 }
206
207 private String addHTMLBreaks(String str) {
208 if (str == null) {
209 return " ";
210 }
211 return str.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
212 }
213
214 public void writeMethod(ServiceMethod method) {
215 writer.indentPrintln("<p>");
216 writer.indentPrintln("<a name=\"" + method.getService() + "-"
217 + method.getName() + "\"></a>");
218 writer.indentPrintln("<p>");
219 writer.indentPrintln("<table class=\"methodTable\">");
220
221 writer.indentPrintln("<tr>");
222 writer.writeTag("th", "class=h", "Method");
223 writer.writeTag("th", "class=h colspan=3 class=\"methodName\"",
224 method.getName());
225 writer.indentPrintln("</tr>");
226
227 writer.indentPrintln("<tr>");
228 writer.writeTag("th", "class=h", "Description");
229 writer.writeTag("td", "colspan=3 class=\"methodDesc\"",
230 this.addHTMLBreaks(calcDescription(method)));
231 writer.indentPrintln("</tr>");
232
233 if (method.getImplNotes() != null && !method.getImplNotes().isEmpty()) {
234 writer.indentPrintln("<tr>");
235 writer.writeTag("th", "class=h", "Implementation Notes");
236 writer.writeTag("td", "colspan=3 class=\"methodDesc\"",
237 this.addHTMLBreaks(method.getImplNotes()));
238 writer.indentPrintln("</tr>");
239 }
240
241 if (method.getParameters().isEmpty()) {
242 writer.indentPrintln("<tr>");
243 writer.writeTag("th", "class=h", "Parameters");
244 writer.writeTag("td", "class=\"methodParamType\"", "None");
245 writer.writeTag("td", "class=\"methodParamName\"", "None");
246 writer.writeTag("td", "class=\"methodParamDesc\"", "No Parameters");
247 writer.indentPrintln("</tr>");
248 } else {
249 boolean firstTime = true;
250 for (ServiceMethodParameter param : method.getParameters()) {
251 writer.indentPrintln("<tr>");
252 if (firstTime) {
253 writer.writeTag("th", "class=h rowspan=" + method.getParameters().size(),
254 "Parameters");
255 firstTime = false;
256 }
257 writer.indentPrint("<td class=\"methodParamType\">");
258 writer.indentPrintln("<a href=\"" + stripListFromType(param.getType())
259 + ".html" + "\">"
260 + param.getType() + "</a>");
261 writer.indentPrint("</td>");
262 writer.writeTag("td", "class=\"methodParamName\"", param.getName());
263 writer.writeTag("td", "class=\"methodParamDesc\"", this.addHTMLBreaks(
264 param.getDescription()));
265 writer.indentPrintln("</tr>");
266 }
267 }
268 writer.indentPrintln("<tr>");
269 writer.writeTag("th", "class=h", "Return");
270 writer.indentPrint("<td colspan=2 class=\"methodReturnType\">");
271 writer.indentPrintln("<a href=\"" + stripListFromType(
272 method.getReturnValue().getType())
273 + ".html" + "\">"
274 + method.getReturnValue().getType() + "</a>");
275 writer.indentPrint("</td>");
276 writer.writeTag("td", "class=\"methodReturnDesc\"",
277 this.addHTMLBreaks(
278 method.getReturnValue().getDescription()));
279 writer.indentPrintln("</tr>");
280 writer.indentPrintln("</tr>");
281
282 if (method.getErrors().isEmpty()) {
283 writer.indentPrintln("<tr>");
284 writer.writeTag("th", "class=h", "Errors");
285 writer.writeTag("td", "class=\"methodErrorType\" colspan=2", "NONE");
286 writer.writeTag("td", "class=\"methodErrorDesc\"", "No Errors");
287 writer.indentPrintln("</tr>");
288 } else {
289 boolean firstTime = true;
290 for (ServiceMethodError error : method.getErrors()) {
291 writer.indentPrintln("<tr>");
292 if (firstTime) {
293 writer.writeTag("th", "class=h rowspan=" + method.getErrors().size(),
294 "Errors");
295 firstTime = false;
296 }
297 writer.writeTag("td", "class=\"methodErrorType\" colspan=2",
298 error.getType()); // TODO wrap in link to type
299 writer.writeTag("td", "class=\"methodErrorDesc\"", this.addHTMLBreaks(
300 error.getDescription()));
301 writer.indentPrintln("</tr>");
302 }
303 }
304 writer.indentPrintln("</table>");
305 writer.indentPrintln("<p>");
306 writer.indentPrintln("<a href=\"#ListOfOperations\">Back to Operations</a>");
307 writer.indentPrintln("<p>");
308 }
309
310 private String calcDescription(ServiceMethod method) {
311 StringBuilder sb = new StringBuilder();
312 String newLine = "";
313 if (method.getDescription() != null && !method.getDescription().trim().isEmpty()) {
314 sb.append(newLine);
315 newLine = "\n";
316 sb.append(method.getDescription());
317 }
318 if (method.isDeprecated()) {
319 sb.append(newLine);
320 newLine = "\n";
321 sb.append("============== Deprecated ===============");
322 }
323 return sb.toString();
324 }
325
326 private static String stripListFromType(String type) {
327 if (type.endsWith("List")) {
328 return type.substring(0, type.length() - "List".length());
329 }
330 return type;
331 }
332
333 public void writeStyleSheet() {
334 writer.indentPrintln("<style type=\"text/css\">");
335 writer.indentPrintln("");
336 writer.indentPrintln("table#serviceMetaTable {");
337 writer.indentPrintln("border-collapse:collapse;");
338 writer.indentPrintln("border:1px solid #000000;");
339 writer.indentPrintln("width:95%;");
340 writer.indentPrintln("}");
341 writer.indentPrintln("table#serviceMetaTable th.h {");
342 writer.indentPrintln("border:1px solid #000000;");
343 writer.indentPrintln("background-color:#eeeeee;");
344 writer.indentPrintln("width:15%;");
345 writer.indentPrintln("}");
346 writer.indentPrintln("table#serviceMetaTable td#serviceName {");
347 writer.indentPrintln("border:1px solid #000000;");
348 writer.indentPrintln("width:85%;");
349 writer.indentPrintln("}");
350 writer.indentPrintln("table#serviceMetaTable td#serviceVersion {");
351 writer.indentPrintln("border:1px solid #000000;");
352 writer.indentPrintln("width:70%;");
353 writer.indentPrintln("}");
354 writer.indentPrintln("table#serviceMetaTable td#serviceVersionHistory {");
355 writer.indentPrintln("border:1px solid #000000;");
356 writer.indentPrintln("width:15%;");
357 writer.indentPrintln("}");
358 writer.indentPrintln("");
359 writer.indentPrintln("</style>");
360
361
362 writer.indentPrintln("<style type=\"text/css\">");
363 writer.indentPrintln("");
364 writer.indentPrintln("table.methodTable {");
365 writer.indentPrintln("border-collapse:collapse;");
366 writer.indentPrintln("border:1px solid #000000;");
367 writer.indentPrintln("width:95%;");
368 writer.indentPrintln("}");
369 writer.indentPrintln("");
370 writer.indentPrintln("table.methodTable td.d {");
371 writer.indentPrintln("border:1px solid #000000;");
372 writer.indentPrintln("}");
373 writer.indentPrintln("");
374 writer.indentPrintln("table.methodTable th.h {");
375 writer.indentPrintln("border:1px solid #000000;");
376 writer.indentPrintln("background-color:#eeeeee;");
377 writer.indentPrintln("width:15%;");
378 writer.indentPrintln("}");
379 writer.indentPrintln("");
380 writer.indentPrintln("table.methodTable td.methodName {");
381 writer.indentPrintln("border:1px solid #000000;");
382 writer.indentPrintln("background-color:#f2f2f2;");
383 writer.indentPrintln("color:#222222;");
384 writer.indentPrintln("text-align:center;");
385 writer.indentPrintln("width:85%;");
386 writer.indentPrintln("font-weight:bold;");
387 writer.indentPrintln("font-style:italic;");
388 writer.indentPrintln("}");
389 writer.indentPrintln("");
390 writer.indentPrintln("table.methodTable td.methodDesc {");
391 writer.indentPrintln("border:1px solid #000000;");
392 writer.indentPrintln("width:85%;");
393 writer.indentPrintln("}");
394 writer.indentPrintln("");
395 writer.indentPrintln("table.methodTable td.methodParamType {");
396 writer.indentPrintln("border:1px solid #000000;");
397 writer.indentPrintln("width:21%;");
398 writer.indentPrintln("font-style:italic;");
399 writer.indentPrintln("}");
400 writer.indentPrintln("table.methodTable td.methodParamName {");
401 writer.indentPrintln("border:1px solid #000000;");
402 writer.indentPrintln("width:21%;");
403 writer.indentPrintln("}");
404 writer.indentPrintln("table.methodTable td.methodParamDesc {");
405 writer.indentPrintln("border:1px solid #000000;");
406 writer.indentPrintln("width:43%;");
407 writer.indentPrintln("}");
408 writer.indentPrintln("table.methodTable td.methodReturnType {");
409 writer.indentPrintln("border:1px solid #000000;");
410 writer.indentPrintln("width:42%;");
411 writer.indentPrintln("font-style:italic;");
412 writer.indentPrintln("}");
413 writer.indentPrintln("");
414 writer.indentPrintln("table.methodTable td.methodReturnDesc {");
415 writer.indentPrintln("border:1px solid #000000;");
416 writer.indentPrintln("width:43%;");
417 writer.indentPrintln("}");
418 writer.indentPrintln("");
419 writer.indentPrintln("table.methodTable td.methodErrors {");
420 writer.indentPrintln("border:1px solid #000000;");
421 writer.indentPrintln("width:85%;");
422 writer.indentPrintln("}");
423 writer.indentPrintln("");
424 writer.indentPrintln("");
425 writer.indentPrintln("table.methodTable td.methodErrorType {");
426 writer.indentPrintln("border:1px solid #000000;");
427 writer.indentPrintln("width:42%;");
428 writer.indentPrintln("font-style:italic;");
429 writer.indentPrintln("}");
430 writer.indentPrintln("table.methodTable td.methodErrorDesc {");
431 writer.indentPrintln("border:1px solid #000000;");
432 writer.indentPrintln("width:43%;");
433 writer.indentPrintln("}");
434 writer.indentPrintln("");
435 writer.indentPrintln("table.methodTable td.capabilityDesc {");
436 writer.indentPrintln("border:1px solid #000000;");
437 writer.indentPrintln("background:#ffffff;");
438 writer.indentPrintln("}");
439 writer.indentPrintln("");
440 writer.indentPrintln("table.methodTable td.usecaseDesc {");
441 writer.indentPrintln("border:1px solid #000000;");
442 writer.indentPrintln("background:#ffffff;");
443 writer.indentPrintln("}");
444 writer.indentPrintln("");
445 writer.indentPrintln("table.methodTable td.commentsDesc {");
446 writer.indentPrintln("border:1px solid #000000;");
447 writer.indentPrintln("background:#ffffff;");
448 writer.indentPrintln("}");
449 writer.indentPrintln("</style>");
450
451 }
452 }