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.HashSet;
19  import java.util.LinkedHashSet;
20  import java.util.Set;
21  
22  import org.kuali.student.contract.model.MessageStructure;
23  import org.kuali.student.contract.model.ServiceContractModel;
24  import org.kuali.student.contract.model.ServiceMethod;
25  import org.kuali.student.contract.model.ServiceMethodParameter;
26  import org.kuali.student.contract.model.XmlType;
27  import org.kuali.student.contract.writer.HtmlWriter;
28  
29  /**
30   *
31   * @author nwright
32   */
33  public class HtmlContractMessageStructureWriter {
34  
35      private XmlType xmlType;
36      private HtmlWriter writer;
37      private ServiceContractModel model;
38      private ModelFinder finder;
39  
40      public HtmlContractMessageStructureWriter(XmlType xmlType, String directory,
41              ServiceContractModel model) {
42          this.xmlType = xmlType;
43          this.writer = new HtmlWriter(directory, xmlType.getName() + ".html",
44                  xmlType.getName());
45          this.model = model;
46          this.finder = new ModelFinder(this.model);
47      }
48  
49      private String initUpper(String str) {
50          if (str == null) {
51              return null;
52          }
53          if (str.length() == 0) {
54              return str;
55          }
56          if (str.length() == 1) {
57              return str.toUpperCase();
58          }
59          return str.substring(0, 1).toUpperCase() + str.substring(1);
60      }
61  
62      private boolean isMainMessageStructure(XmlType xmlType) {
63          if (!HtmlContractMessageStructureWriter.calcOtherXmlTypeUsages(model,
64                  xmlType).isEmpty()) {
65              return false;
66          }
67          return true;
68      }
69  
70      public void write(String projectVersion, String formattedDate) {
71         
72          this.writeStyleSheet();
73         
74          
75          if (this.isMainMessageStructure(xmlType)) {
76          	VersionLinesUtility.writeVersionTag(writer, "<a href=\"index.html\">home</a>", "<a href=\"../dictionarydocs/" + initUpper(xmlType.getName()) + ".html\">dictionary doc</a>", projectVersion, formattedDate);
77          }
78          else 
79          	VersionLinesUtility.writeVersionTag(writer, "<a href=\"index.html\">home</a>", "" ,projectVersion, formattedDate);
80          
81  
82          writer.writeTag("h1", xmlType.getName());
83          
84          writer.indentPrintln("<table id=\"structureMetaTable\">");
85          writer.indentPrintln("<tr>");
86          writer.writeTag("th", "class=h", "Name");
87          writer.writeTag("td", "id=structureName colspan=2", xmlType.getName());
88          writer.indentPrintln("</tr>");
89  //  writer.indentPrintln ("<tr>");
90  //  writer.writeTag ("th", "class=h", "Version");
91  //  writer.writeTag ("td", "id=structureVersion colspan=2", xmlType.getVersion ());
92  //  writer.indentPrintln ("</tr>");
93          writer.indentPrintln("<tr>");
94          writer.writeTag("th", "rowspan=3 class=h", "Usage");
95          writer.indentPrint("<td id=\"structureVersion\" colspan=2>");
96          for (String servKey : xmlType.getService().split(",")) {
97              writer.indentPrintln("<a href=\"" + servKey + "Service" + ".html" + "\">"
98                      + servKey + "Service" + "</a>");
99          }
100         writer.indentPrint("</td>");
101 
102         writer.indentPrintln("</tr>");
103         writer.indentPrintln("<tr>");
104         writer.writeTag("th", "class=h", "");
105         writer.indentPrint("<td id=\"structureVersion\" colspan=2>");
106         for (ServiceMethod method : this.calcUsageByMethods(xmlType)) {
107             writer.indentPrintln("<a href=\"" + method.getService() + "Service"
108                     + ".html" + "#" + method.getService() + "-"
109                     + method.getName() + "\">"
110                     + method.getName() + "</a>");
111         }
112         writer.indentPrint("</td>");
113         writer.indentPrintln("</tr>");
114         writer.indentPrintln("<tr>");
115         writer.writeTag("th", "class=h", "");
116         writer.indentPrint("<td id=\"structureVersion\" colspan=2>");
117         for (String xmlTypeName : this.calcOtherXmlTypeUsages(xmlType)) {
118             XmlType usageType = finder.findXmlType(xmlTypeName);
119             if (usageType == null) {
120                 throw new NullPointerException("Coud not find XmlType with name="
121                         + xmlTypeName);
122             }
123             writer.indentPrintln("<a href=\"" + usageType.getName() + ".html" + "\">"
124                     + usageType.getName() + "</a>");
125         }
126         writer.indentPrint("</td>");
127         writer.indentPrintln("</tr>");
128 
129         writer.writeTag("th", "class=h", "Type");
130         writer.writeTag("td", "id=structureVersion colspan=2",
131                 xmlType.getPrimitive());
132         writer.indentPrintln("</tr>");
133         writer.indentPrintln("</table>");
134 
135         writer.writeTag("h2", "Description");
136         writer.indentPrintln(this.addHTMLBreaks(calcDescription (xmlType)));
137 
138         if (!xmlType.getPrimitive().equals(XmlType.COMPLEX)) {
139             return;
140         }
141         writer.indentPrintln(
142                 "<h2><a name=\"StructureDefinition\"></a>Structure Definition</h2>");
143 
144 
145         writer.indentPrintln("<table class=\"structTable\">");
146         writer.indentPrintln("<tr>");
147         writer.indentPrintln("<th class=\"h\">ShortName</th>");
148         writer.indentPrintln("<th class=\"h\">Name</th>");
149         writer.indentPrintln("<th class=\"h\">Type</th>");
150         writer.indentPrintln("<th class=\"h\">Description</th>");
151         writer.indentPrintln("<th class=\"h\">Required?</th>");
152         writer.indentPrintln("<th class=\"h\">Read only?</th>");
153         writer.indentPrintln("<th class=\"h\">Cardinality</th>");
154         writer.indentPrintln("<th class=\"h\">XML Attribute?</th>");
155 //        writer.indentPrintln ("<th class=\"h\">Status</th>"); 
156         writer.indentPrintln("<th class=\"h\">Implementation Notes</th>");
157         writer.indentPrintln("</tr>");
158 
159         for (MessageStructure ms : finder.findMessageStructures(xmlType.getName())) {
160             this.writeMessageStructure(ms);
161         }
162         writer.indentPrintln("</table>");
163         writer.writeHeaderBodyAndFooterOutToFile();
164     }
165 
166     
167      private String calcDescription(XmlType xmlType) {
168         StringBuilder sb = new StringBuilder();
169         String newLine = "";
170         if (xmlType.getDesc() != null && !xmlType.getDesc().trim().isEmpty()) {
171             sb.append(newLine);
172             newLine = "\n";
173             sb.append(xmlType.getDesc ());
174         }
175         if (xmlType.isDeprecated()) {
176             sb.append(newLine);
177             newLine = "\n";
178             sb.append("============== Deprecated ===============");
179         }
180         return sb.toString();
181     }
182 
183     private String checkForNbsp(String str) {
184         if (str == null) {
185             return "&nbsp;";
186         }
187         if (str.trim().isEmpty()) {
188             return "&nbsp;";
189         }
190         return str;
191     }
192 
193     private String addHTMLBreaks(String str) {
194         if (str == null) {
195             return "&nbsp;";
196         }
197         return str.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
198     }
199 
200     public static Set<String> calcUsageByService(ServiceContractModel mdl, XmlType xmlType) {
201         Set<String> services = new HashSet();
202         for (ServiceMethod method : calcUsageByMethods(mdl, xmlType)) {
203             services.add(method.getService());
204         }
205         return services;
206     }
207 
208     private Set<ServiceMethod> calcUsageByMethods(XmlType xmlType) {
209         return calcUsageByMethods(model, xmlType);
210     }
211 
212     public static Set<ServiceMethod> calcUsageByMethods(ServiceContractModel mdl, XmlType xmlType) {
213         Set<ServiceMethod> methods = new LinkedHashSet();
214         for (ServiceMethod method : mdl.getServiceMethods()) {
215             if (stripListFromType(method.getReturnValue().getType()).equalsIgnoreCase(xmlType.getName())) {
216                 methods.add(method);
217                 continue;
218             }
219             for (ServiceMethodParameter param : method.getParameters()) {
220                 if (stripListFromType(param.getType()).equalsIgnoreCase(xmlType.getName())) {
221                     methods.add(method);
222                     break;
223                 }
224             }
225         }
226         return methods;
227     }
228 
229     private Set<String> calcOtherXmlTypeUsages(XmlType xmlType) {
230         return calcOtherXmlTypeUsages(model, xmlType);
231     }
232 
233     public static Set<String> calcOtherXmlTypeUsages(ServiceContractModel mdl,
234             XmlType xmlType) {
235         Set<String> xmlTypeNames = new LinkedHashSet();
236         for (MessageStructure ms : mdl.getMessageStructures()) {
237             if (ms.getType() == null) {
238                 throw new NullPointerException(ms.getId() + " has no type set");
239             }
240             if (stripListFromType(ms.getType()).equalsIgnoreCase(xmlType.getName())) {
241                 xmlTypeNames.add(ms.getXmlObject());
242             }
243         }
244         return xmlTypeNames;
245     }
246 
247     private void writeMessageStructure(MessageStructure ms) {
248         writer.indentPrintln("<tr>");
249         writer.writeTag("td", "class=\"structSName\"", ms.getShortName());
250         writer.writeTag("td", "class=\"structLName\"", ms.getName());
251         XmlType subType = finder.findXmlType(this.stripListFromType(ms.getType()));
252         if (subType == null) {
253             for (XmlType xmlt : model.getXmlTypes()) {
254                 System.out.println(this.getClass().getSimpleName() + ": "
255                         + xmlt.getName());
256             }
257             throw new NullPointerException(ms.getXmlObject() + "." + ms.getShortName()
258                     + " has type " + ms.getType()
259                     + " was not found in list of known types");
260         }
261         if (subType.getPrimitive().equals(XmlType.COMPLEX)) {
262             writer.indentPrint("<td class=\"structType\">");
263             writer.indentPrintln("<a href=\"" + subType.getName() + ".html" + "\">"
264                     + ms.getType() + "</a>");
265             writer.indentPrint("</td>");
266         } else {
267             writer.writeTag("td", "class=\"structType\"", ms.getType());
268         }
269         writer.writeTag("td", "class=\"structDesc\"", addHTMLBreaks(missingData(
270                 calcDescription(ms))));
271         writer.writeTag("td", "class=\"structOpt\"", checkForNbsp(ms.getRequired()));
272         writer.writeTag("td", "class=\"structOpt\"", checkForNbsp(ms.getReadOnly()));
273 
274         writer.writeTag("td", "class=\"structCard\"", ms.getCardinality());
275         writer.writeTag("td", "class=\"structAttr\"", ms.getXmlAttribute());
276 //      writer.writeTag ("td", "class=\"structStatus\"", ms.getStatus ());
277         writer.writeTag("td", "class=\"commentsDesc\"", addHTMLBreaks(this.checkForNbsp(ms.getImplNotes())));
278         writer.indentPrintln("</tr>");
279 
280 //  writer.indentPrintln ("</table>");
281 //  writer.indentPrintln ("<p>");
282 
283 //  writer.indentPrintln ("<p>");
284     }
285 
286     private String calcDescription(MessageStructure ms) {
287         StringBuilder sb = new StringBuilder();
288         String newLine = "";
289         if (ms.getDescription() != null && !ms.getDescription().trim().isEmpty()) {
290             sb.append(newLine);
291             newLine = "\n";
292             sb.append(ms.getDescription());
293         }
294         if (ms.isDeprecated()) {
295             sb.append(newLine);
296             newLine = "\n";
297             sb.append("============== Deprecated ===============");
298         }
299         return sb.toString();
300     }
301 
302     private String missingData(String str) {
303         if (str == null) {
304             return "???";
305         }
306         if (str.trim().isEmpty()) {
307             return "???";
308         }
309         return str;
310     }
311 
312     private static String stripListFromType(String type) {
313         if (type.endsWith("List")) {
314             return type.substring(0, type.length() - "List".length());
315         }
316         return type;
317     }
318 
319     public void writeStyleSheet() {
320         writer.indentPrintln("<style type=\"text/css\">");
321         writer.indentPrintln("");
322         writer.indentPrintln("table#structureMetaTable {");
323         writer.indentPrintln("border-collapse:collapse;");
324         writer.indentPrintln("border:1px solid #000000;");
325         writer.indentPrintln("width:95%;");
326         writer.indentPrintln("}");
327         writer.indentPrintln("table#structureMetaTable th.h {");
328         writer.indentPrintln("border:1px solid #000000;");
329         writer.indentPrintln("background-color:#eeeeee;");
330         writer.indentPrintln("width:15%;");
331         writer.indentPrintln("}");
332         writer.indentPrintln("table#structureMetaTable td#structureName {");
333         writer.indentPrintln("border:1px solid #000000;");
334         writer.indentPrintln("width:85%;");
335         writer.indentPrintln("}");
336         writer.indentPrintln("table#structureMetaTable td#structureVersion {");
337         writer.indentPrintln("border:1px solid #000000;");
338         writer.indentPrintln("width:70%;");
339         writer.indentPrintln("}");
340         writer.indentPrintln("table#structureMetaTable td#structureVersionHistory {");
341         writer.indentPrintln("border:1px solid #000000;");
342         writer.indentPrintln("width:15%;");
343         writer.indentPrintln("}");
344         writer.indentPrintln("");
345         writer.indentPrintln("</style>");
346 
347         writer.indentPrintln("<style type=\"text/css\">");
348         writer.indentPrintln("");
349         writer.indentPrintln("table.structTable {");
350         writer.indentPrintln("border-collapse:collapse;");
351         writer.indentPrintln("border:1px solid #000000;");
352         writer.indentPrintln("width:95%;");
353         writer.indentPrintln("}");
354         writer.indentPrintln("");
355         writer.indentPrintln("table.structTable td.d {");
356         writer.indentPrintln("border:1px solid #000000;");
357         writer.indentPrintln("}");
358         writer.indentPrintln("");
359         writer.indentPrintln("table.structTable th.h {");
360         writer.indentPrintln("border:1px solid #000000;");
361         writer.indentPrintln("background-color:#eeeeee;");
362         writer.indentPrintln("}");
363         writer.indentPrintln("");
364         writer.indentPrintln("table.structTable td.structSName {");
365         writer.indentPrintln("border:1px solid #000000;");
366         writer.indentPrintln("background-color:#f2f2f2;");
367         writer.indentPrintln("color:#222222;");
368         writer.indentPrintln("text-align:left;");
369         writer.indentPrintln("vertical-align:top;");
370         writer.indentPrintln("font-weight:bold;");
371         writer.indentPrintln("font-style:italic;");
372         writer.indentPrintln("");
373         writer.indentPrintln("}");
374         writer.indentPrintln("");
375         writer.indentPrintln("table.structTable td.structLName {");
376         writer.indentPrintln("border:1px solid #000000;");
377         writer.indentPrintln("background:#ffffff;");
378         writer.indentPrintln("vertical-align:top;");
379         writer.indentPrintln("");
380         writer.indentPrintln("}");
381         writer.indentPrintln("");
382         writer.indentPrintln("table.structTable td.structType {");
383         writer.indentPrintln("border:1px solid #000000;");
384         writer.indentPrintln("background:#ffffff;");
385         writer.indentPrintln("vertical-align:top;");
386         writer.indentPrintln("font-style:italic;");
387         writer.indentPrintln("");
388         writer.indentPrintln("}");
389         writer.indentPrintln("");
390         writer.indentPrintln("table.structTable td.structDesc {");
391         writer.indentPrintln("border:1px solid #000000;");
392         writer.indentPrintln("background:#ffffff;");
393         writer.indentPrintln("vertical-align:top;");
394         writer.indentPrintln("");
395         writer.indentPrintln("}");
396         writer.indentPrintln("");
397         writer.indentPrintln("table.structTable td.structOpt {");
398         writer.indentPrintln("border:1px solid #000000;");
399         writer.indentPrintln("background:#ffffff;");
400         writer.indentPrintln("vertical-align:top;");
401         writer.indentPrintln("text-align: center;");
402         writer.indentPrintln("}");
403         writer.indentPrintln("");
404         writer.indentPrintln("table.structTable td.structReq {");
405         writer.indentPrintln("border:1px solid #000000;");
406         writer.indentPrintln("background:#ccccff;");
407         writer.indentPrintln("vertical-align:top;");
408         writer.indentPrintln("text-align: center;");
409         writer.indentPrintln("}");
410         writer.indentPrintln("");
411         writer.indentPrintln("");
412         writer.indentPrintln("table.structTable td.structCard {");
413         writer.indentPrintln("border:1px solid #000000;");
414         writer.indentPrintln("background:#ffffff;");
415         writer.indentPrintln("vertical-align:top;");
416         writer.indentPrintln("text-align: center;");
417         writer.indentPrintln("}");
418         writer.indentPrintln("");
419         writer.indentPrintln("table.structTable td.structAttr {");
420         writer.indentPrintln("border:1px solid #000000;");
421         writer.indentPrintln("background:#ffffff;");
422         writer.indentPrintln("vertical-align:top;");
423         writer.indentPrintln("text-align: center;");
424         writer.indentPrintln("}");
425         writer.indentPrintln("");
426         writer.indentPrintln("table.structTable td.structElem {");
427         writer.indentPrintln("border:1px solid #000000;");
428         writer.indentPrintln("background:#ccccff;");
429         writer.indentPrintln("vertical-align:top;");
430         writer.indentPrintln("text-align: center;");
431         writer.indentPrintln("}");
432         writer.indentPrintln("");
433         writer.indentPrintln("table.structTable td.structStatus {");
434         writer.indentPrintln("border:1px solid #000000;");
435         writer.indentPrintln("background:#ffffff;");
436         writer.indentPrintln("vertical-align:top;");
437         writer.indentPrintln("text-align: center;");
438         writer.indentPrintln("");
439         writer.indentPrintln("}");
440         writer.indentPrintln("");
441         writer.indentPrintln("table.structTable td.commentsDesc {");
442         writer.indentPrintln("border:1px solid #000000;");
443         writer.indentPrintln("background:#ffffff;");
444         writer.indentPrintln("vertical-align:top;");
445         writer.indentPrintln("");
446         writer.indentPrintln("}");
447         writer.indentPrintln("");
448         writer.indentPrintln("");
449         writer.indentPrintln("</style>");
450 
451 
452     }
453 }