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