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(xmlType.getDesc()));
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     private String checkForNbsp(String str) {
161         if (str == null) {
162             return "&nbsp;";
163         }
164         if (str.trim().isEmpty()) {
165             return "&nbsp;";
166         }
167         return str;
168     }
169 
170     private String addHTMLBreaks(String str) {
171         if (str == null) {
172             return "&nbsp;";
173         }
174         return str.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
175     }
176 
177     public static Set<String> calcUsageByService(ServiceContractModel mdl, XmlType xmlType) {
178         Set<String> services = new HashSet();
179         for (ServiceMethod method : calcUsageByMethods(mdl, xmlType)) {
180             services.add(method.getService());
181         }
182         return services;
183     }
184 
185     private Set<ServiceMethod> calcUsageByMethods(XmlType xmlType) {
186         return calcUsageByMethods(model, xmlType);
187     }
188 
189     public static Set<ServiceMethod> calcUsageByMethods(ServiceContractModel mdl, XmlType xmlType) {
190         Set<ServiceMethod> methods = new LinkedHashSet();
191         for (ServiceMethod method : mdl.getServiceMethods()) {
192             if (stripListFromType(method.getReturnValue().getType()).equalsIgnoreCase(xmlType.getName())) {
193                 methods.add(method);
194                 continue;
195             }
196             for (ServiceMethodParameter param : method.getParameters()) {
197                 if (stripListFromType(param.getType()).equalsIgnoreCase(xmlType.getName())) {
198                     methods.add(method);
199                     break;
200                 }
201             }
202         }
203         return methods;
204     }
205 
206     private Set<String> calcOtherXmlTypeUsages(XmlType xmlType) {
207         return calcOtherXmlTypeUsages(model, xmlType);
208     }
209 
210     public static Set<String> calcOtherXmlTypeUsages(ServiceContractModel mdl,
211             XmlType xmlType) {
212         Set<String> xmlTypeNames = new LinkedHashSet();
213         for (MessageStructure ms : mdl.getMessageStructures()) {
214             if (ms.getType() == null) {
215                 throw new NullPointerException(ms.getId() + " has no type set");
216             }
217             if (stripListFromType(ms.getType()).equalsIgnoreCase(xmlType.getName())) {
218                 xmlTypeNames.add(ms.getXmlObject());
219             }
220         }
221         return xmlTypeNames;
222     }
223 
224     private void writeMessageStructure(MessageStructure ms) {
225         writer.indentPrintln("<tr>");
226         writer.writeTag("td", "class=\"structSName\"", ms.getShortName());
227         writer.writeTag("td", "class=\"structLName\"", ms.getName());
228         XmlType subType = finder.findXmlType(this.stripListFromType(ms.getType()));
229         if (subType == null) {
230             for (XmlType xmlt : model.getXmlTypes()) {
231                 System.out.println(this.getClass().getSimpleName() + ": "
232                         + xmlt.getName());
233             }
234             throw new NullPointerException(ms.getXmlObject() + "." + ms.getShortName()
235                     + " has type " + ms.getType()
236                     + " was not found in list of known types");
237         }
238         if (subType.getPrimitive().equals(XmlType.COMPLEX)) {
239             writer.indentPrint("<td class=\"structType\">");
240             writer.indentPrintln("<a href=\"" + subType.getName() + ".html" + "\">"
241                     + ms.getType() + "</a>");
242             writer.indentPrint("</td>");
243         } else {
244             writer.writeTag("td", "class=\"structType\"", ms.getType());
245         }
246         writer.writeTag("td", "class=\"structDesc\"", addHTMLBreaks(missingData(
247                 ms.getDescription())));
248         writer.writeTag("td", "class=\"structOpt\"", checkForNbsp(ms.getRequired()));
249         writer.writeTag("td", "class=\"structOpt\"", checkForNbsp(ms.getReadOnly()));
250 
251         writer.writeTag("td", "class=\"structCard\"", ms.getCardinality());
252         writer.writeTag("td", "class=\"structAttr\"", ms.getXmlAttribute());
253 //      writer.writeTag ("td", "class=\"structStatus\"", ms.getStatus ());
254         writer.writeTag("td", "class=\"commentsDesc\"", this.checkForNbsp(ms.getImplNotes()));
255         writer.indentPrintln("</tr>");
256 
257 //  writer.indentPrintln ("</table>");
258 //  writer.indentPrintln ("<p>");
259 
260 //  writer.indentPrintln ("<p>");
261     }
262 
263     private String missingData(String str) {
264         if (str == null) {
265             return "???";
266         }
267         if (str.trim().isEmpty()) {
268             return "???";
269         }
270         return str;
271     }
272 
273     private static String stripListFromType(String type) {
274         if (type.endsWith("List")) {
275             return type.substring(0, type.length() - "List".length());
276         }
277         return type;
278     }
279 
280     public void writeStyleSheet() {
281         writer.indentPrintln("<style type=\"text/css\">");
282         writer.indentPrintln("");
283         writer.indentPrintln("table#structureMetaTable {");
284         writer.indentPrintln("border-collapse:collapse;");
285         writer.indentPrintln("border:1px solid #000000;");
286         writer.indentPrintln("width:95%;");
287         writer.indentPrintln("}");
288         writer.indentPrintln("table#structureMetaTable th.h {");
289         writer.indentPrintln("border:1px solid #000000;");
290         writer.indentPrintln("background-color:#eeeeee;");
291         writer.indentPrintln("width:15%;");
292         writer.indentPrintln("}");
293         writer.indentPrintln("table#structureMetaTable td#structureName {");
294         writer.indentPrintln("border:1px solid #000000;");
295         writer.indentPrintln("width:85%;");
296         writer.indentPrintln("}");
297         writer.indentPrintln("table#structureMetaTable td#structureVersion {");
298         writer.indentPrintln("border:1px solid #000000;");
299         writer.indentPrintln("width:70%;");
300         writer.indentPrintln("}");
301         writer.indentPrintln("table#structureMetaTable td#structureVersionHistory {");
302         writer.indentPrintln("border:1px solid #000000;");
303         writer.indentPrintln("width:15%;");
304         writer.indentPrintln("}");
305         writer.indentPrintln("");
306         writer.indentPrintln("</style>");
307 
308         writer.indentPrintln("<style type=\"text/css\">");
309         writer.indentPrintln("");
310         writer.indentPrintln("table.structTable {");
311         writer.indentPrintln("border-collapse:collapse;");
312         writer.indentPrintln("border:1px solid #000000;");
313         writer.indentPrintln("width:95%;");
314         writer.indentPrintln("}");
315         writer.indentPrintln("");
316         writer.indentPrintln("table.structTable td.d {");
317         writer.indentPrintln("border:1px solid #000000;");
318         writer.indentPrintln("}");
319         writer.indentPrintln("");
320         writer.indentPrintln("table.structTable th.h {");
321         writer.indentPrintln("border:1px solid #000000;");
322         writer.indentPrintln("background-color:#eeeeee;");
323         writer.indentPrintln("}");
324         writer.indentPrintln("");
325         writer.indentPrintln("table.structTable td.structSName {");
326         writer.indentPrintln("border:1px solid #000000;");
327         writer.indentPrintln("background-color:#f2f2f2;");
328         writer.indentPrintln("color:#222222;");
329         writer.indentPrintln("text-align:left;");
330         writer.indentPrintln("vertical-align:top;");
331         writer.indentPrintln("font-weight:bold;");
332         writer.indentPrintln("font-style:italic;");
333         writer.indentPrintln("");
334         writer.indentPrintln("}");
335         writer.indentPrintln("");
336         writer.indentPrintln("table.structTable td.structLName {");
337         writer.indentPrintln("border:1px solid #000000;");
338         writer.indentPrintln("background:#ffffff;");
339         writer.indentPrintln("vertical-align:top;");
340         writer.indentPrintln("");
341         writer.indentPrintln("}");
342         writer.indentPrintln("");
343         writer.indentPrintln("table.structTable td.structType {");
344         writer.indentPrintln("border:1px solid #000000;");
345         writer.indentPrintln("background:#ffffff;");
346         writer.indentPrintln("vertical-align:top;");
347         writer.indentPrintln("font-style:italic;");
348         writer.indentPrintln("");
349         writer.indentPrintln("}");
350         writer.indentPrintln("");
351         writer.indentPrintln("table.structTable td.structDesc {");
352         writer.indentPrintln("border:1px solid #000000;");
353         writer.indentPrintln("background:#ffffff;");
354         writer.indentPrintln("vertical-align:top;");
355         writer.indentPrintln("");
356         writer.indentPrintln("}");
357         writer.indentPrintln("");
358         writer.indentPrintln("table.structTable td.structOpt {");
359         writer.indentPrintln("border:1px solid #000000;");
360         writer.indentPrintln("background:#ffffff;");
361         writer.indentPrintln("vertical-align:top;");
362         writer.indentPrintln("text-align: center;");
363         writer.indentPrintln("}");
364         writer.indentPrintln("");
365         writer.indentPrintln("table.structTable td.structReq {");
366         writer.indentPrintln("border:1px solid #000000;");
367         writer.indentPrintln("background:#ccccff;");
368         writer.indentPrintln("vertical-align:top;");
369         writer.indentPrintln("text-align: center;");
370         writer.indentPrintln("}");
371         writer.indentPrintln("");
372         writer.indentPrintln("");
373         writer.indentPrintln("table.structTable td.structCard {");
374         writer.indentPrintln("border:1px solid #000000;");
375         writer.indentPrintln("background:#ffffff;");
376         writer.indentPrintln("vertical-align:top;");
377         writer.indentPrintln("text-align: center;");
378         writer.indentPrintln("}");
379         writer.indentPrintln("");
380         writer.indentPrintln("table.structTable td.structAttr {");
381         writer.indentPrintln("border:1px solid #000000;");
382         writer.indentPrintln("background:#ffffff;");
383         writer.indentPrintln("vertical-align:top;");
384         writer.indentPrintln("text-align: center;");
385         writer.indentPrintln("}");
386         writer.indentPrintln("");
387         writer.indentPrintln("table.structTable td.structElem {");
388         writer.indentPrintln("border:1px solid #000000;");
389         writer.indentPrintln("background:#ccccff;");
390         writer.indentPrintln("vertical-align:top;");
391         writer.indentPrintln("text-align: center;");
392         writer.indentPrintln("}");
393         writer.indentPrintln("");
394         writer.indentPrintln("table.structTable td.structStatus {");
395         writer.indentPrintln("border:1px solid #000000;");
396         writer.indentPrintln("background:#ffffff;");
397         writer.indentPrintln("vertical-align:top;");
398         writer.indentPrintln("text-align: center;");
399         writer.indentPrintln("");
400         writer.indentPrintln("}");
401         writer.indentPrintln("");
402         writer.indentPrintln("table.structTable td.commentsDesc {");
403         writer.indentPrintln("border:1px solid #000000;");
404         writer.indentPrintln("background:#ffffff;");
405         writer.indentPrintln("vertical-align:top;");
406         writer.indentPrintln("");
407         writer.indentPrintln("}");
408         writer.indentPrintln("");
409         writer.indentPrintln("");
410         writer.indentPrintln("</style>");
411 
412 
413     }
414 }