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