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.getName() + ".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", "Name");
062 writer.writeTag("td", "id=serviceName colspan=2", service.getKey());
063 writer.indentPrintln("</tr>");
064 writer.indentPrintln("<tr>");
065 writer.writeTag("th", "class=h", "Version");
066 writer.writeTag("td", "id=serviceVersion colspan=2", service.getVersion());
067 writer.indentPrintln("</tr>");
068 writer.indentPrintln("<tr>");
069 writer.writeTag("th", "class=h", "Included Services");
070
071 writer.writeTag("td", "id=serviceVersion colspan=2", calcIncludedServices(
072 service.getIncludedServices()));
073 writer.indentPrintln("</tr>");
074
075 writer.indentPrintln("</table>");
076
077 // writer.indentPrintln ("<div class=\"panel\" style=\"border-width: 1px;\">");
078 // writer.indentPrintln ("<div class=\"panelHeader\" style=\"border-bottom-width: 1px;\">");
079 writer.indentPrintln("<p>");
080 // writer.indentPrintln("<table id=\"serviceMetaTable\">");
081 // writer.indentPrintln("<tr>");
082 // writer.indentPrintln("<td>");
083 writer.indentPrintln(
084 "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
085 writer.indentPrintln(
086 "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
087 writer.indentPrintln(this.addHTMLBreaks(service.getComments()));
088 writer.indentPrintln("</div>");
089 writer.indentPrintln("</div>");
090 // writer.indentPrintln("</td>");
091 // writer.indentPrintln("</tr>");
092 // writer.indentPrintln("</table>");
093
094 // writer.indentPrintln ("</div>");
095 // writer.indentPrintln ("</div>");
096
097 writer.indentPrintln("<p>");
098 writer.indentPrintln(
099 "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
100 writer.indentPrintln(
101 "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
102 writer.indentPrintln("<b><a name=\"ListOfOperations\"></a>Operations</b>");
103 writer.indentPrintln(
104 "</div><div class=\"panelContent\" style=\"background-color: rgb(255, 255, 255);\">");
105 writer.indentPrintln("<ul>");
106 for (ServiceMethod method : finder.getServiceMethodsInService(
107 service.getKey())) {
108 writer.indentPrint("<li>");
109 writer.print("<a href=\"#" + method.getService() + "-" + method.getName()
110 + "\">" + method.getName() + "</a>");
111 writer.print("</li>");
112 }
113 writer.indentPrintln("</ul>");
114 writer.indentPrintln("</div>");
115 writer.indentPrintln("</div>");
116
117 // now write out the root message structures
118 writer.indentPrintln(
119 "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
120 writer.indentPrintln(
121 "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
122 writer.indentPrintln(
123 "<b><a name=\"MainMessageStructures\"></a>Main Message Structures</b>");
124 writer.indentPrintln(
125 "</div><div class=\"panelContent\" style=\"background-color: rgb(255, 255, 255);\">");
126
127 writer.indentPrintln("<ul>");
128 for (XmlType type : this.calcMainMessageStructures()) {
129 writer.indentPrint("<li>");
130 writer.print("<a href=\"" + type.getName() + ".html"
131 + "\">" + type.getName() + "</a>");
132 writer.print("</li>");
133 }
134 writer.indentPrintln("</ul>");
135
136
137 for (ServiceMethod method : finder.getServiceMethodsInService(
138 service.getKey())) {
139 this.writeMethod(method);
140 }
141
142 writer.writeHeaderBodyAndFooterOutToFile();
143 }
144
145 private String calcIncludedServices(List<String> includedServices) {
146 if (includedServices == null) {
147 return " ";
148 }
149 if (includedServices.isEmpty()) {
150 return " ";
151 }
152 StringBuilder bldr = new StringBuilder();
153 String comma = "";
154 for (String includedService : includedServices) {
155 bldr.append(comma);
156 comma = ", ";
157 bldr.append("<a href=\"" + includedService + ".html"
158 + "\">" + includedService + "</a>");
159 }
160 return bldr.toString();
161 }
162
163 private Set<XmlType> calcMainMessageStructures() {
164 return calcMainMessageStructures(model, service.getKey());
165 }
166
167 public static Set<XmlType> calcMainMessageStructures(ServiceContractModel mdl,
168 String serviceOptionaFilter) {
169 ModelFinder fndr = new ModelFinder(mdl);
170 Set<XmlType> types = new LinkedHashSet();
171 for (ServiceMethod method : mdl.getServiceMethods()) {
172 if (serviceOptionaFilter != null) {
173 if (!method.getService().equalsIgnoreCase(serviceOptionaFilter)) {
174 continue;
175 }
176 }
177 XmlType type = fndr.findXmlType(stripListFromType(method.getReturnValue().getType()));
178 if (type != null) {
179 if (type.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
180 types.add(type);
181 }
182 }
183
184 for (ServiceMethodParameter param : method.getParameters()) {
185 type = fndr.findXmlType(stripListFromType(param.getType()));
186 if (type != null) {
187 if (type.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
188 types.add(type);
189 }
190 }
191 break;
192 }
193 }
194 return types;
195 }
196
197 private String addHTMLBreaks(String str) {
198 if (str == null) {
199 return " ";
200 }
201 return str.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
202 }
203
204 public void writeMethod(ServiceMethod method) {
205 writer.indentPrintln("<p>");
206 writer.indentPrintln("<a name=\"" + method.getService() + "-"
207 + method.getName() + "\"></a>");
208 writer.indentPrintln("<p>");
209 writer.indentPrintln("<table class=\"methodTable\">");
210
211 writer.indentPrintln("<tr>");
212 writer.writeTag("th", "class=h", "Method");
213 writer.writeTag("th", "class=h colspan=3 class=\"methodName\"",
214 method.getName());
215 writer.indentPrintln("</tr>");
216
217 writer.indentPrintln("<tr>");
218 writer.writeTag("th", "class=h", "Description");
219 writer.writeTag("td", "colspan=3 class=\"methodDesc\"",
220 this.addHTMLBreaks(calcDescription(method)));
221 writer.indentPrintln("</tr>");
222
223 if (method.getImplNotes() != null && !method.getImplNotes().isEmpty()) {
224 writer.indentPrintln("<tr>");
225 writer.writeTag("th", "class=h", "Implementation Notes");
226 writer.writeTag("td", "colspan=3 class=\"methodDesc\"",
227 this.addHTMLBreaks(method.getImplNotes()));
228 writer.indentPrintln("</tr>");
229 }
230
231 if (method.getParameters().isEmpty()) {
232 writer.indentPrintln("<tr>");
233 writer.writeTag("th", "class=h", "Parameters");
234 writer.writeTag("td", "class=\"methodParamType\"", "None");
235 writer.writeTag("td", "class=\"methodParamName\"", "None");
236 writer.writeTag("td", "class=\"methodParamDesc\"", "No Parameters");
237 writer.indentPrintln("</tr>");
238 } else {
239 boolean firstTime = true;
240 for (ServiceMethodParameter param : method.getParameters()) {
241 writer.indentPrintln("<tr>");
242 if (firstTime) {
243 writer.writeTag("th", "class=h rowspan=" + method.getParameters().size(),
244 "Parameters");
245 firstTime = false;
246 }
247 writer.indentPrint("<td class=\"methodParamType\">");
248 writer.indentPrintln("<a href=\"" + stripListFromType(param.getType())
249 + ".html" + "\">"
250 + param.getType() + "</a>");
251 writer.indentPrint("</td>");
252 writer.writeTag("td", "class=\"methodParamName\"", param.getName());
253 writer.writeTag("td", "class=\"methodParamDesc\"", this.addHTMLBreaks(
254 param.getDescription()));
255 writer.indentPrintln("</tr>");
256 }
257 }
258 writer.indentPrintln("<tr>");
259 writer.writeTag("th", "class=h", "Return");
260 writer.indentPrint("<td colspan=2 class=\"methodReturnType\">");
261 writer.indentPrintln("<a href=\"" + stripListFromType(
262 method.getReturnValue().getType())
263 + ".html" + "\">"
264 + method.getReturnValue().getType() + "</a>");
265 writer.indentPrint("</td>");
266 writer.writeTag("td", "class=\"methodReturnDesc\"",
267 this.addHTMLBreaks(
268 method.getReturnValue().getDescription()));
269 writer.indentPrintln("</tr>");
270 writer.indentPrintln("</tr>");
271
272 if (method.getErrors().isEmpty()) {
273 writer.indentPrintln("<tr>");
274 writer.writeTag("th", "class=h", "Errors");
275 writer.writeTag("td", "class=\"methodErrorType\" colspan=2", "NONE");
276 writer.writeTag("td", "class=\"methodErrorDesc\"", "No Errors");
277 writer.indentPrintln("</tr>");
278 } else {
279 boolean firstTime = true;
280 for (ServiceMethodError error : method.getErrors()) {
281 writer.indentPrintln("<tr>");
282 if (firstTime) {
283 writer.writeTag("th", "class=h rowspan=" + method.getErrors().size(),
284 "Errors");
285 firstTime = false;
286 }
287 writer.writeTag("td", "class=\"methodErrorType\" colspan=2",
288 error.getType()); // TODO wrap in link to type
289 writer.writeTag("td", "class=\"methodErrorDesc\"", this.addHTMLBreaks(
290 error.getDescription()));
291 writer.indentPrintln("</tr>");
292 }
293 }
294 writer.indentPrintln("</table>");
295 writer.indentPrintln("<p>");
296 writer.indentPrintln("<a href=\"#ListOfOperations\">Back to Operations</a>");
297 writer.indentPrintln("<p>");
298 }
299
300 private String calcDescription(ServiceMethod method) {
301 StringBuilder sb = new StringBuilder();
302 String newLine = "";
303 if (method.getDescription() != null && !method.getDescription().trim().isEmpty()) {
304 sb.append(newLine);
305 newLine = "\n";
306 sb.append(method.getDescription());
307 }
308 if (method.isDeprecated()) {
309 sb.append(newLine);
310 newLine = "\n";
311 sb.append("============== Deprecated ===============");
312 }
313 return sb.toString();
314 }
315
316 private static String stripListFromType(String type) {
317 if (type.endsWith("List")) {
318 return type.substring(0, type.length() - "List".length());
319 }
320 return type;
321 }
322
323 public void writeStyleSheet() {
324 writer.indentPrintln("<style type=\"text/css\">");
325 writer.indentPrintln("");
326 writer.indentPrintln("table#serviceMetaTable {");
327 writer.indentPrintln("border-collapse:collapse;");
328 writer.indentPrintln("border:1px solid #000000;");
329 writer.indentPrintln("width:95%;");
330 writer.indentPrintln("}");
331 writer.indentPrintln("table#serviceMetaTable th.h {");
332 writer.indentPrintln("border:1px solid #000000;");
333 writer.indentPrintln("background-color:#eeeeee;");
334 writer.indentPrintln("width:15%;");
335 writer.indentPrintln("}");
336 writer.indentPrintln("table#serviceMetaTable td#serviceName {");
337 writer.indentPrintln("border:1px solid #000000;");
338 writer.indentPrintln("width:85%;");
339 writer.indentPrintln("}");
340 writer.indentPrintln("table#serviceMetaTable td#serviceVersion {");
341 writer.indentPrintln("border:1px solid #000000;");
342 writer.indentPrintln("width:70%;");
343 writer.indentPrintln("}");
344 writer.indentPrintln("table#serviceMetaTable td#serviceVersionHistory {");
345 writer.indentPrintln("border:1px solid #000000;");
346 writer.indentPrintln("width:15%;");
347 writer.indentPrintln("}");
348 writer.indentPrintln("");
349 writer.indentPrintln("</style>");
350
351
352 writer.indentPrintln("<style type=\"text/css\">");
353 writer.indentPrintln("");
354 writer.indentPrintln("table.methodTable {");
355 writer.indentPrintln("border-collapse:collapse;");
356 writer.indentPrintln("border:1px solid #000000;");
357 writer.indentPrintln("width:95%;");
358 writer.indentPrintln("}");
359 writer.indentPrintln("");
360 writer.indentPrintln("table.methodTable td.d {");
361 writer.indentPrintln("border:1px solid #000000;");
362 writer.indentPrintln("}");
363 writer.indentPrintln("");
364 writer.indentPrintln("table.methodTable th.h {");
365 writer.indentPrintln("border:1px solid #000000;");
366 writer.indentPrintln("background-color:#eeeeee;");
367 writer.indentPrintln("width:15%;");
368 writer.indentPrintln("}");
369 writer.indentPrintln("");
370 writer.indentPrintln("table.methodTable td.methodName {");
371 writer.indentPrintln("border:1px solid #000000;");
372 writer.indentPrintln("background-color:#f2f2f2;");
373 writer.indentPrintln("color:#222222;");
374 writer.indentPrintln("text-align:center;");
375 writer.indentPrintln("width:85%;");
376 writer.indentPrintln("font-weight:bold;");
377 writer.indentPrintln("font-style:italic;");
378 writer.indentPrintln("}");
379 writer.indentPrintln("");
380 writer.indentPrintln("table.methodTable td.methodDesc {");
381 writer.indentPrintln("border:1px solid #000000;");
382 writer.indentPrintln("width:85%;");
383 writer.indentPrintln("}");
384 writer.indentPrintln("");
385 writer.indentPrintln("table.methodTable td.methodParamType {");
386 writer.indentPrintln("border:1px solid #000000;");
387 writer.indentPrintln("width:21%;");
388 writer.indentPrintln("font-style:italic;");
389 writer.indentPrintln("}");
390 writer.indentPrintln("table.methodTable td.methodParamName {");
391 writer.indentPrintln("border:1px solid #000000;");
392 writer.indentPrintln("width:21%;");
393 writer.indentPrintln("}");
394 writer.indentPrintln("table.methodTable td.methodParamDesc {");
395 writer.indentPrintln("border:1px solid #000000;");
396 writer.indentPrintln("width:43%;");
397 writer.indentPrintln("}");
398 writer.indentPrintln("table.methodTable td.methodReturnType {");
399 writer.indentPrintln("border:1px solid #000000;");
400 writer.indentPrintln("width:42%;");
401 writer.indentPrintln("font-style:italic;");
402 writer.indentPrintln("}");
403 writer.indentPrintln("");
404 writer.indentPrintln("table.methodTable td.methodReturnDesc {");
405 writer.indentPrintln("border:1px solid #000000;");
406 writer.indentPrintln("width:43%;");
407 writer.indentPrintln("}");
408 writer.indentPrintln("");
409 writer.indentPrintln("table.methodTable td.methodErrors {");
410 writer.indentPrintln("border:1px solid #000000;");
411 writer.indentPrintln("width:85%;");
412 writer.indentPrintln("}");
413 writer.indentPrintln("");
414 writer.indentPrintln("");
415 writer.indentPrintln("table.methodTable td.methodErrorType {");
416 writer.indentPrintln("border:1px solid #000000;");
417 writer.indentPrintln("width:42%;");
418 writer.indentPrintln("font-style:italic;");
419 writer.indentPrintln("}");
420 writer.indentPrintln("table.methodTable td.methodErrorDesc {");
421 writer.indentPrintln("border:1px solid #000000;");
422 writer.indentPrintln("width:43%;");
423 writer.indentPrintln("}");
424 writer.indentPrintln("");
425 writer.indentPrintln("table.methodTable td.capabilityDesc {");
426 writer.indentPrintln("border:1px solid #000000;");
427 writer.indentPrintln("background:#ffffff;");
428 writer.indentPrintln("}");
429 writer.indentPrintln("");
430 writer.indentPrintln("table.methodTable td.usecaseDesc {");
431 writer.indentPrintln("border:1px solid #000000;");
432 writer.indentPrintln("background:#ffffff;");
433 writer.indentPrintln("}");
434 writer.indentPrintln("");
435 writer.indentPrintln("table.methodTable td.commentsDesc {");
436 writer.indentPrintln("border:1px solid #000000;");
437 writer.indentPrintln("background:#ffffff;");
438 writer.indentPrintln("}");
439 writer.indentPrintln("</style>");
440
441 }
442 }