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 }