View Javadoc

1   /*
2    * Copyright 2011 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may	obtain a copy of the License at
7    *
8    * 	http://www.osedu.org/licenses/ECL-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.student.contract.model.util;
17  
18  import java.util.Date;
19  import java.util.LinkedHashSet;
20  import java.util.List;
21  import java.util.Set;
22  
23  import org.kuali.student.contract.model.Service;
24  import org.kuali.student.contract.model.ServiceContractModel;
25  import org.kuali.student.contract.model.ServiceMethod;
26  import org.kuali.student.contract.model.ServiceMethodError;
27  import org.kuali.student.contract.model.ServiceMethodParameter;
28  import org.kuali.student.contract.model.XmlType;
29  import org.kuali.student.contract.writer.HtmlWriter;
30  
31  /**
32   *
33   * @author nwright
34   */
35  public class HtmlContractServiceWriter {
36  
37      private Service service;
38      private HtmlWriter writer;
39      private ServiceContractModel model;
40      private ModelFinder finder;
41  
42      public HtmlContractServiceWriter(Service service, String directory,
43              ServiceContractModel model) {
44          this.service = service;
45          this.writer = new HtmlWriter(directory, service.getName() + ".html",
46                  service.getName());
47          this.model = model;
48          this.finder = new ModelFinder(this.model);
49      }
50  
51      public void write(String projectVersion, String formattedDate) {
52          this.writeStyleSheet();
53         
54  
55          VersionLinesUtility.writeVersionTag(writer, "<a href=\"index.html\">home</a>", "", projectVersion, formattedDate);
56  
57          writer.writeTag("h1", service.getName());
58          
59          writer.indentPrintln("<table id=\"serviceMetaTable\">");
60          writer.indentPrintln("<tr>");
61          writer.writeTag("th", "class=h", "Name");
62          writer.writeTag("td", "id=serviceName colspan=2", service.getKey());
63          writer.indentPrintln("</tr>");
64          writer.indentPrintln("<tr>");
65          writer.writeTag("th", "class=h", "Version");
66          writer.writeTag("td", "id=serviceVersion colspan=2", service.getVersion());
67          writer.indentPrintln("</tr>");
68          writer.indentPrintln("<tr>");
69          writer.writeTag("th", "class=h", "Included Services");
70  
71          writer.writeTag("td", "id=serviceVersion colspan=2", calcIncludedServices(
72                  service.getIncludedServices()));
73          writer.indentPrintln("</tr>");
74  
75          writer.indentPrintln("</table>");
76  
77  //  writer.indentPrintln ("<div class=\"panel\" style=\"border-width: 1px;\">");
78  //  writer.indentPrintln ("<div class=\"panelHeader\" style=\"border-bottom-width: 1px;\">");
79          writer.indentPrintln("<p>");
80  //        writer.indentPrintln("<table id=\"serviceMetaTable\">");
81  //        writer.indentPrintln("<tr>");
82  //        writer.indentPrintln("<td>");
83          writer.indentPrintln(
84                  "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
85            writer.indentPrintln(
86                  "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
87          writer.indentPrintln(this.addHTMLBreaks(service.getComments()));
88          writer.indentPrintln("</div>");
89          writer.indentPrintln("</div>");
90  //        writer.indentPrintln("</td>");
91  //        writer.indentPrintln("</tr>");
92  //        writer.indentPrintln("</table>");
93  
94  //  writer.indentPrintln ("</div>");
95  //  writer.indentPrintln ("</div>");
96  
97          writer.indentPrintln("<p>");
98          writer.indentPrintln(
99                  "<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 "&nbsp;";
148         }
149         if (includedServices.isEmpty()) {
150             return "&nbsp;";
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 "&nbsp;";
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 }