001    /*
002     * Copyright 2011 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may      obtain a copy of the License at
007     *
008     *      http://www.osedu.org/licenses/ECL-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.student.contract.model.util;
017    
018    import java.util.LinkedHashSet;
019    import java.util.List;
020    import java.util.Set;
021    
022    import org.kuali.student.contract.model.Service;
023    import org.kuali.student.contract.model.ServiceContractModel;
024    import org.kuali.student.contract.model.ServiceMethod;
025    import org.kuali.student.contract.model.ServiceMethodError;
026    import org.kuali.student.contract.model.ServiceMethodParameter;
027    import org.kuali.student.contract.model.XmlType;
028    import org.kuali.student.contract.writer.HtmlWriter;
029    
030    /**
031     *
032     * @author nwright
033     */
034    public class HtmlContractServiceWriter {
035    
036        private Service service;
037        private HtmlWriter writer;
038        private ServiceContractModel model;
039        private ModelFinder finder;
040    
041        public HtmlContractServiceWriter(Service service, String directory,
042                ServiceContractModel model) {
043            this.service = service;
044            this.writer = new HtmlWriter(directory, service.getName() + ".html",
045                    service.getName());
046            this.model = model;
047            this.finder = new ModelFinder(this.model);
048        }
049    
050        public void write() {
051            writer.print("<a href=\"index.html\">home</a>");
052            this.writeStyleSheet();
053            writer.writeTag("h1", service.getName());
054    
055            writer.indentPrintln("<table id=\"serviceMetaTable\">");
056            writer.indentPrintln("<tr>");
057            writer.writeTag("th", "class=h", "Name");
058            writer.writeTag("td", "id=serviceName colspan=2", service.getKey());
059            writer.indentPrintln("</tr>");
060            writer.indentPrintln("<tr>");
061            writer.writeTag("th", "class=h", "Version");
062            writer.writeTag("td", "id=serviceVersion colspan=2", service.getVersion());
063            writer.indentPrintln("</tr>");
064            writer.indentPrintln("<tr>");
065            writer.writeTag("th", "class=h", "Included Services");
066    
067            writer.writeTag("td", "id=serviceVersion colspan=2", calcIncludedServices(
068                    service.getIncludedServices()));
069            writer.indentPrintln("</tr>");
070    
071            writer.indentPrintln("</table>");
072    
073    //  writer.indentPrintln ("<div class=\"panel\" style=\"border-width: 1px;\">");
074    //  writer.indentPrintln ("<div class=\"panelHeader\" style=\"border-bottom-width: 1px;\">");
075            writer.indentPrintln("<p>");
076            writer.indentPrintln("<table id=\"serviceMetaTable\">");
077            writer.indentPrintln("<tr>");
078            writer.indentPrintln("<th class=h>");
079            writer.indentPrintln(this.addHTMLBreaks(service.getComments()));
080            writer.indentPrintln("</th>");
081            writer.indentPrintln("</tr>");
082            writer.indentPrintln("</table>");
083    
084    //  writer.indentPrintln ("</div>");
085    //  writer.indentPrintln ("</div>");
086    
087            writer.indentPrintln(
088                    "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
089            writer.indentPrintln(
090                    "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
091            writer.indentPrintln("<b><a name=\"ListOfOperations\"></a>Operations</b>");
092            writer.indentPrintln(
093                    "</div><div class=\"panelContent\" style=\"background-color: rgb(255, 255, 255);\">");
094            writer.indentPrintln("<ul>");
095            for (ServiceMethod method : finder.getServiceMethodsInService(
096                    service.getKey())) {
097                writer.indentPrint("<li>");
098                writer.print("<a href=\"#" + method.getService() + "-" + method.getName()
099                        + "\">" + method.getName() + "</a>");
100                writer.print("</li>");
101            }
102            writer.indentPrintln("</ul>");
103            writer.indentPrintln("</div>");
104            writer.indentPrintln("</div>");
105    
106            // now write out the root message structures
107            writer.indentPrintln(
108                    "<div class=\"panel\" style=\"background-color: rgb(255, 255, 255); border: 1px solid rgb(204, 204, 204);\">");
109            writer.indentPrintln(
110                    "<div class=\"panelHeader\" style=\"border-bottom: 1px solid rgb(204, 204, 204); background-color: rgb(238, 238, 238);\">");
111            writer.indentPrintln(
112                    "<b><a name=\"MainMessageStructures\"></a>Main Message Structures</b>");
113            writer.indentPrintln(
114                    "</div><div class=\"panelContent\" style=\"background-color: rgb(255, 255, 255);\">");
115    
116            writer.indentPrintln("<ul>");
117            for (XmlType type : this.calcMainMessageStructures()) {
118                writer.indentPrint("<li>");
119                writer.print("<a href=\"" + type.getName() + ".html"
120                        + "\">" + type.getName() + "</a>");
121                writer.print("</li>");
122            }
123            writer.indentPrintln("</ul>");
124    
125    
126            for (ServiceMethod method : finder.getServiceMethodsInService(
127                    service.getKey())) {
128                this.writeMethod(method);
129            }
130    
131            writer.writeHeaderBodyAndFooterOutToFile();
132        }
133    
134        private String calcIncludedServices(List<String> includedServices) {
135            if (includedServices == null) {
136                return "&nbsp;";
137            }
138            if (includedServices.isEmpty()) {
139                return "&nbsp;";
140            }
141            StringBuilder bldr = new StringBuilder();
142            String comma = "";
143            for (String includedService : includedServices) {
144                bldr.append(comma);
145                comma = ", ";
146                bldr.append("<a href=\"" + includedService + ".html"
147                        + "\">" + includedService + "</a>");
148            }
149            return bldr.toString();
150        }
151    
152        private Set<XmlType> calcMainMessageStructures() {
153            return calcMainMessageStructures(model, service.getKey());
154        }
155    
156        public static Set<XmlType> calcMainMessageStructures(ServiceContractModel mdl,
157                String serviceOptionaFilter) {
158            ModelFinder fndr = new ModelFinder(mdl);
159            Set<XmlType> types = new LinkedHashSet();
160            for (ServiceMethod method : mdl.getServiceMethods()) {
161                if (serviceOptionaFilter != null) {
162                    if (!method.getService().equalsIgnoreCase(serviceOptionaFilter)) {
163                        continue;
164                    }
165                }
166                XmlType type = fndr.findXmlType(stripListFromType(method.getReturnValue().getType()));
167                if (type != null) {
168                    if (type.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
169                        types.add(type);
170                    }
171                }
172    
173                for (ServiceMethodParameter param : method.getParameters()) {
174                    type = fndr.findXmlType(stripListFromType(param.getType()));
175                    if (type != null) {
176                        if (type.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
177                            types.add(type);
178                        }
179                    }
180                    break;
181                }
182            }
183            return types;
184        }
185    
186        private String addHTMLBreaks(String str) {
187            if (str == null) {
188                return "&nbsp;";
189            }
190            return str.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
191        }
192    
193        public void writeMethod(ServiceMethod method) {
194            writer.indentPrintln("<p>");
195            writer.indentPrintln("<a name=\"" + method.getService() + "-"
196                    + method.getName() + "\"></a>");
197            writer.indentPrintln("<p>");
198            writer.indentPrintln("<table class=\"methodTable\">");
199    
200            writer.indentPrintln("<tr>");
201            writer.writeTag("th", "class=h", "Method");
202            writer.writeTag("th", "class=h colspan=3 class=\"methodName\"",
203                    method.getName());
204            writer.indentPrintln("</tr>");
205    
206            writer.indentPrintln("<tr>");
207            writer.writeTag("th", "class=h", "Description");
208            writer.writeTag("td", "colspan=3 class=\"methodDesc\"",
209                    this.addHTMLBreaks(method.getDescription()));
210            writer.indentPrintln("</tr>");
211    
212            if (method.getParameters().isEmpty()) {
213                writer.indentPrintln("<tr>");
214                writer.writeTag("th", "class=h", "Parameters");
215                writer.writeTag("td", "class=\"methodParamType\"", "None");
216                writer.writeTag("td", "class=\"methodParamName\"", "None");
217                writer.writeTag("td", "class=\"methodParamDesc\"", "No Parameters");
218                writer.indentPrintln("</tr>");
219            } else {
220                boolean firstTime = true;
221                for (ServiceMethodParameter param : method.getParameters()) {
222                    writer.indentPrintln("<tr>");
223                    if (firstTime) {
224                        writer.writeTag("th", "class=h rowspan=" + method.getParameters().size(),
225                                "Parameters");
226                        firstTime = false;
227                    }
228                    writer.indentPrint("<td class=\"methodParamType\">");
229                    writer.indentPrintln("<a href=\"" + stripListFromType(param.getType())
230                            + ".html" + "\">"
231                            + param.getType() + "</a>");
232                    writer.indentPrint("</td>");
233                    writer.writeTag("td", "class=\"methodParamName\"", param.getName());
234                    writer.writeTag("td", "class=\"methodParamDesc\"", this.addHTMLBreaks(
235                            param.getDescription()));
236                    writer.indentPrintln("</tr>");
237                }
238            }
239            writer.indentPrintln("<tr>");
240            writer.writeTag("th", "class=h", "Return");
241            writer.indentPrint("<td colspan=2 class=\"methodReturnType\">");
242            writer.indentPrintln("<a href=\"" + stripListFromType(
243                    method.getReturnValue().getType())
244                    + ".html" + "\">"
245                    + method.getReturnValue().getType() + "</a>");
246            writer.indentPrint("</td>");
247            writer.writeTag("td", "class=\"methodReturnDesc\"",
248                    this.addHTMLBreaks(
249                    method.getReturnValue().getDescription()));
250            writer.indentPrintln("</tr>");
251            writer.indentPrintln("</tr>");
252    
253            if (method.getErrors().isEmpty()) {
254                writer.indentPrintln("<tr>");
255                writer.writeTag("th", "class=h", "Errors");
256                writer.writeTag("td", "class=\"methodErrorType\" colspan=2", "NONE");
257                writer.writeTag("td", "class=\"methodErrorDesc\"", "No Errors");
258                writer.indentPrintln("</tr>");
259            } else {
260                boolean firstTime = true;
261                for (ServiceMethodError error : method.getErrors()) {
262                    writer.indentPrintln("<tr>");
263                    if (firstTime) {
264                        writer.writeTag("th", "class=h rowspan=" + method.getErrors().size(),
265                                "Errors");
266                        firstTime = false;
267                    }
268                    writer.writeTag("td", "class=\"methodErrorType\" colspan=2",
269                            error.getType()); // TODO wrap in link to type
270                    writer.writeTag("td", "class=\"methodErrorDesc\"", this.addHTMLBreaks(
271                            error.getDescription()));
272                    writer.indentPrintln("</tr>");
273                }
274            }
275            writer.indentPrintln("</table>");
276            writer.indentPrintln("<p>");
277            writer.indentPrintln("<a href=\"#ListOfOperations\">Back to Operations</a>");
278            writer.indentPrintln("<p>");
279        }
280    
281        private static String stripListFromType(String type) {
282            if (type.endsWith("List")) {
283                return type.substring(0, type.length() - "List".length());
284            }
285            return type;
286        }
287    
288        public void writeStyleSheet() {
289            writer.indentPrintln("<style type=\"text/css\">");
290            writer.indentPrintln("");
291            writer.indentPrintln("table#serviceMetaTable {");
292            writer.indentPrintln("border-collapse:collapse;");
293            writer.indentPrintln("border:1px solid #000000;");
294            writer.indentPrintln("width:95%;");
295            writer.indentPrintln("}");
296            writer.indentPrintln("table#serviceMetaTable th.h {");
297            writer.indentPrintln("border:1px solid #000000;");
298            writer.indentPrintln("background-color:#eeeeee;");
299            writer.indentPrintln("width:15%;");
300            writer.indentPrintln("}");
301            writer.indentPrintln("table#serviceMetaTable td#serviceName {");
302            writer.indentPrintln("border:1px solid #000000;");
303            writer.indentPrintln("width:85%;");
304            writer.indentPrintln("}");
305            writer.indentPrintln("table#serviceMetaTable td#serviceVersion {");
306            writer.indentPrintln("border:1px solid #000000;");
307            writer.indentPrintln("width:70%;");
308            writer.indentPrintln("}");
309            writer.indentPrintln("table#serviceMetaTable td#serviceVersionHistory {");
310            writer.indentPrintln("border:1px solid #000000;");
311            writer.indentPrintln("width:15%;");
312            writer.indentPrintln("}");
313            writer.indentPrintln("");
314            writer.indentPrintln("</style>");
315    
316    
317            writer.indentPrintln("<style type=\"text/css\">");
318            writer.indentPrintln("");
319            writer.indentPrintln("table.methodTable {");
320            writer.indentPrintln("border-collapse:collapse;");
321            writer.indentPrintln("border:1px solid #000000;");
322            writer.indentPrintln("width:95%;");
323            writer.indentPrintln("}");
324            writer.indentPrintln("");
325            writer.indentPrintln("table.methodTable td.d {");
326            writer.indentPrintln("border:1px solid #000000;");
327            writer.indentPrintln("}");
328            writer.indentPrintln("");
329            writer.indentPrintln("table.methodTable th.h {");
330            writer.indentPrintln("border:1px solid #000000;");
331            writer.indentPrintln("background-color:#eeeeee;");
332            writer.indentPrintln("width:15%;");
333            writer.indentPrintln("}");
334            writer.indentPrintln("");
335            writer.indentPrintln("table.methodTable td.methodName {");
336            writer.indentPrintln("border:1px solid #000000;");
337            writer.indentPrintln("background-color:#f2f2f2;");
338            writer.indentPrintln("color:#222222;");
339            writer.indentPrintln("text-align:center;");
340            writer.indentPrintln("width:85%;");
341            writer.indentPrintln("font-weight:bold;");
342            writer.indentPrintln("font-style:italic;");
343            writer.indentPrintln("}");
344            writer.indentPrintln("");
345            writer.indentPrintln("table.methodTable td.methodDesc {");
346            writer.indentPrintln("border:1px solid #000000;");
347            writer.indentPrintln("width:85%;");
348            writer.indentPrintln("}");
349            writer.indentPrintln("");
350            writer.indentPrintln("table.methodTable td.methodParamType {");
351            writer.indentPrintln("border:1px solid #000000;");
352            writer.indentPrintln("width:21%;");
353            writer.indentPrintln("font-style:italic;");
354            writer.indentPrintln("}");
355            writer.indentPrintln("table.methodTable td.methodParamName {");
356            writer.indentPrintln("border:1px solid #000000;");
357            writer.indentPrintln("width:21%;");
358            writer.indentPrintln("}");
359            writer.indentPrintln("table.methodTable td.methodParamDesc {");
360            writer.indentPrintln("border:1px solid #000000;");
361            writer.indentPrintln("width:43%;");
362            writer.indentPrintln("}");
363            writer.indentPrintln("table.methodTable td.methodReturnType {");
364            writer.indentPrintln("border:1px solid #000000;");
365            writer.indentPrintln("width:42%;");
366            writer.indentPrintln("font-style:italic;");
367            writer.indentPrintln("}");
368            writer.indentPrintln("");
369            writer.indentPrintln("table.methodTable td.methodReturnDesc {");
370            writer.indentPrintln("border:1px solid #000000;");
371            writer.indentPrintln("width:43%;");
372            writer.indentPrintln("}");
373            writer.indentPrintln("");
374            writer.indentPrintln("table.methodTable td.methodErrors {");
375            writer.indentPrintln("border:1px solid #000000;");
376            writer.indentPrintln("width:85%;");
377            writer.indentPrintln("}");
378            writer.indentPrintln("");
379            writer.indentPrintln("");
380            writer.indentPrintln("table.methodTable td.methodErrorType {");
381            writer.indentPrintln("border:1px solid #000000;");
382            writer.indentPrintln("width:42%;");
383            writer.indentPrintln("font-style:italic;");
384            writer.indentPrintln("}");
385            writer.indentPrintln("table.methodTable td.methodErrorDesc {");
386            writer.indentPrintln("border:1px solid #000000;");
387            writer.indentPrintln("width:43%;");
388            writer.indentPrintln("}");
389            writer.indentPrintln("");
390            writer.indentPrintln("table.methodTable td.capabilityDesc {");
391            writer.indentPrintln("border:1px solid #000000;");
392            writer.indentPrintln("background:#ffffff;");
393            writer.indentPrintln("}");
394            writer.indentPrintln("");
395            writer.indentPrintln("table.methodTable td.usecaseDesc {");
396            writer.indentPrintln("border:1px solid #000000;");
397            writer.indentPrintln("background:#ffffff;");
398            writer.indentPrintln("}");
399            writer.indentPrintln("");
400            writer.indentPrintln("table.methodTable td.commentsDesc {");
401            writer.indentPrintln("border:1px solid #000000;");
402            writer.indentPrintln("background:#ffffff;");
403            writer.indentPrintln("}");
404            writer.indentPrintln("</style>");
405    
406        }
407    }