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