Clover Coverage Report - KS Contract Documentation Generator 0.0.1-SNAPSHOT
Coverage timestamp: Wed Dec 31 1969 19:00:00 EST
../../../../../../img/srcFileCovDistChart0.png 0% of files have more coverage
195   533   75   5.27
70   395   0.38   9.25
37     2.03  
4    
 
  ServiceContractModelPescXsdLoader       Line # 60 185 0% 57 271 0% 0.0
  ServiceContractModelPescXsdLoader.XsdAnnotationParserFactory       Line # 428 1 0% 1 2 0% 0.0
  ServiceContractModelPescXsdLoader.XsdAnnotationParser       Line # 439 2 0% 2 4 0% 0.0
  ServiceContractModelPescXsdLoader.XsdContentHandler       Line # 460 7 0% 15 25 0% 0.0
 
No Tests
 
1    /*
2    * Copyright 2010 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.impl;
17   
18    import com.sun.xml.xsom.XSAnnotation;
19    import com.sun.xml.xsom.XSComplexType;
20    import com.sun.xml.xsom.XSContentType;
21    import com.sun.xml.xsom.XSElementDecl;
22    import com.sun.xml.xsom.XSFacet;
23    import com.sun.xml.xsom.XSModelGroup;
24    import com.sun.xml.xsom.XSParticle;
25    import com.sun.xml.xsom.XSSchema;
26    import com.sun.xml.xsom.XSSchemaSet;
27    import com.sun.xml.xsom.XSSimpleType;
28    import com.sun.xml.xsom.XSTerm;
29    import com.sun.xml.xsom.XSType;
30    import com.sun.xml.xsom.parser.AnnotationContext;
31    import com.sun.xml.xsom.parser.AnnotationParser;
32    import com.sun.xml.xsom.parser.AnnotationParserFactory;
33    import com.sun.xml.xsom.parser.SchemaDocument;
34    import com.sun.xml.xsom.parser.XSOMParser;
35    import com.sun.xml.xsom.util.DomAnnotationParserFactory;
36    import java.io.File;
37    import java.io.IOException;
38    import java.util.ArrayList;
39    import java.util.LinkedHashMap;
40    import java.util.List;
41    import java.util.Map;
42    import java.util.Set;
43    import org.kuali.student.contract.model.MessageStructure;
44    import org.kuali.student.contract.model.Service;
45    import org.kuali.student.contract.model.ServiceContractModel;
46    import org.kuali.student.contract.model.ServiceMethod;
47    import org.kuali.student.contract.model.ServiceMethodReturnValue;
48    import org.kuali.student.contract.model.XmlType;
49    import org.xml.sax.Attributes;
50    import org.xml.sax.ContentHandler;
51    import org.xml.sax.EntityResolver;
52    import org.xml.sax.ErrorHandler;
53    import org.xml.sax.Locator;
54    import org.xml.sax.SAXException;
55   
56    /**
57    *
58    * @author nwright
59    */
 
60    public class ServiceContractModelPescXsdLoader implements
61    ServiceContractModel {
62   
63    private List<String> xsdFileNames;
64    private List<Service> services = null;
65    private List<ServiceMethod> serviceMethods = null;
66    private Map<String, XmlType> xmlTypeMap = null;
67    private List<MessageStructure> messageStructures;
68   
 
69  0 toggle public ServiceContractModelPescXsdLoader(List<String> xsdFileNames) {
70  0 this.xsdFileNames = xsdFileNames;
71    }
72   
 
73  0 toggle @Override
74    public List<ServiceMethod> getServiceMethods() {
75  0 if (this.serviceMethods == null) {
76  0 this.parse();
77    }
78  0 return this.serviceMethods;
79    }
80   
 
81  0 toggle @Override
82    public List<String> getSourceNames() {
83  0 List<String> list = new ArrayList();
84  0 list.addAll(this.xsdFileNames);
85  0 return list;
86    }
87   
 
88  0 toggle @Override
89    public List<Service> getServices() {
90  0 if (services == null) {
91  0 this.parse();
92    }
93  0 return services;
94    }
95   
 
96  0 toggle @Override
97    public List<XmlType> getXmlTypes() {
98  0 if (xmlTypeMap == null) {
99  0 this.parse();
100    }
101  0 return new ArrayList(xmlTypeMap.values());
102    }
103   
 
104  0 toggle @Override
105    public List<MessageStructure> getMessageStructures() {
106  0 if (messageStructures == null) {
107  0 this.parse();
108    }
109  0 return this.messageStructures;
110    }
111   
 
112  0 toggle private void parse() {
113  0 System.out.println("ServiceContractModelQDoxLoader: Starting parse");
114  0 services = new ArrayList();
115  0 Service service = new Service();
116  0 services.add(service);
117  0 service.setKey("Pesc");
118  0 service.setName("PescService");
119  0 service.setComments("Derived from pesc CoreMain");
120  0 serviceMethods = new ArrayList();
121  0 ServiceMethod method = new ServiceMethod();
122  0 serviceMethods.add(method);
123  0 method.setName("dummy");
124  0 method.setDescription("Dummy method so validation won't fail");
125  0 method.setService("Pesc");
126  0 method.setParameters(new ArrayList());
127  0 ServiceMethodReturnValue rv = new ServiceMethodReturnValue();
128  0 rv.setType("void");
129  0 rv.setDescription("returns nothing");
130  0 method.setReturnValue(rv);
131  0 xmlTypeMap = new LinkedHashMap();
132  0 messageStructures = new ArrayList();
133   
134  0 XSOMParser parser = new XSOMParser();
135  0 parser.setAnnotationParser(new DomAnnotationParserFactory());
136    // parser.setAnnotationParser(new XsdAnnotationParserFactory());
137  0 try {
138  0 for (String xsdFileName : this.xsdFileNames) {
139    // System.out.println("Parsing " + xsdFileName);
140  0 parser.parse(new File(xsdFileName));
141    }
142    } catch (SAXException ex) {
143  0 throw new IllegalArgumentException(ex);
144    } catch (IOException ex) {
145  0 throw new IllegalArgumentException(ex);
146    }
147  0 XSSchemaSet schemas;
148  0 try {
149  0 schemas = parser.getResult();
150    } catch (SAXException ex) {
151  0 throw new IllegalArgumentException(ex);
152    }
153    // for (XSSchema schema : schemas.getSchemas()) {
154    // this.processSchema(schema);
155    // }
156  0 Set<SchemaDocument> schemaDocuments = parser.getDocuments();
157  0 for (SchemaDocument doc : schemaDocuments) {
158  0 XSSchema schema = doc.getSchema();
159  0 this.processSchema(schema);
160    }
161    }
162   
 
163  0 toggle private void processSchema(XSSchema schema) {
164  0 for (XSElementDecl element : schema.getElementDecls().values()) {
165  0 this.addElementDecl(element);
166    }
167  0 for (XSSimpleType st : schema.getSimpleTypes().values()) {
168    // System.out.println("SimpleType =" + st.getName() + " namespace=" + st.getTargetNamespace());
169  0 addSimpleType(st);
170    }
171  0 for (XSComplexType ct : schema.getComplexTypes().values()) {
172  0 if (!shouldInclude(ct)) {
173    // System.out.println("Skipping ComplexType =" + ct.getName() + " namespace=" + ct.getTargetNamespace());
174  0 continue;
175    }
176    // System.out.println("ComplexType =" + ct.getName() + " namespace=" + ct.getTargetNamespace());
177  0 addComplexType(ct);
178    }
179    }
180   
 
181  0 toggle private boolean shouldInclude(XSComplexType ct) {
182    // if (ct.getTargetNamespace().equals("urn:org:pesc:core:CoreMain:v1.8.0")) {
183  0 return true;
184    // }
185    // return false;
186    }
187   
 
188  0 toggle private void addSimpleType(XSSimpleType simpleType) {
189  0 XmlType xmlType = xmlTypeMap.get(simpleType.getName());
190  0 if (xmlType != null) {
191    // System.out.println("Already processed simple Type="
192    // + simpleType.getName());
193  0 return;
194    }
195  0 xmlType = new XmlType();
196  0 xmlTypeMap.put(simpleType.getName(), xmlType);
197  0 xmlType.setName(simpleType.getName());
198  0 xmlType.setDesc(calcMissing(calcDesc(simpleType.getAnnotation())));
199  0 xmlType.setComments("???");
200  0 xmlType.setExamples("???");
201  0 xmlType.setService("Pesc");
202  0 xmlType.setPrimitive("Primitive");
203    }
204   
 
205  0 toggle private void addComplexType(XSComplexType complexType) {
206  0 addComplexType(complexType, complexType.getName());
207    }
208   
 
209  0 toggle private void addElementDecl(XSElementDecl element) {
210  0 String name = element.getName();
211  0 XmlType xmlType = xmlTypeMap.get(name);
212  0 if (xmlType != null) {
213    // System.out.println("Already processed element name=" + name);
214  0 return;
215    }
216    // System.out.println("processing element=" + name);
217  0 xmlType = new XmlType();
218  0 xmlTypeMap.put(name, xmlType);
219  0 xmlType.setName(name);
220  0 xmlType.setDesc(calcMissing(calcDesc(element.getAnnotation())));
221  0 xmlType.setComments("???");
222  0 xmlType.setExamples("???");
223  0 xmlType.setService("Pesc");
224  0 xmlType.setPrimitive(XmlType.COMPLEX);
225  0 addMessageStructure(xmlType.getName(), element);
226    }
227   
 
228  0 toggle private void addComplexType(XSComplexType complexType, String name) {
229  0 XmlType xmlType = xmlTypeMap.get(name);
230  0 if (xmlType != null) {
231    // System.out.println("Already processed complex Type=" + name);
232  0 return;
233    }
234    // System.out.println("processing complex type=" + name);
235  0 xmlType = new XmlType();
236  0 xmlTypeMap.put(name, xmlType);
237  0 xmlType.setName(name);
238  0 xmlType.setDesc(calcMissing(calcDesc(complexType.getAnnotation())));
239  0 xmlType.setComments("???");
240  0 xmlType.setExamples("???");
241  0 xmlType.setService("Pesc");
242  0 xmlType.setPrimitive(XmlType.COMPLEX);
243   
244  0 boolean found = false;
245  0 XSContentType contentType = complexType.getContentType();
246  0 XSParticle particle = contentType.asParticle();
247  0 if (particle != null) {
248  0 XSTerm term = particle.getTerm();
249  0 if (term.isModelGroup()) {
250  0 XSModelGroup xsModelGroup = term.asModelGroup();
251  0 XSParticle[] particles = xsModelGroup.getChildren();
252  0 for (XSParticle p : particles) {
253  0 XSTerm pterm = p.getTerm();
254  0 if (pterm.isElementDecl()) { //xs:element inside complex type
255  0 XSElementDecl element = pterm.asElementDecl();
256  0 addMessageStructure(xmlType.getName(), element);
257  0 found = true;
258    }
259    }
260    }
261    }
262    // if (!found) {
263    // System.out.println("*** WARNING *** Complex Type, " + xmlType.getName() + ", has no message structure fields");
264    // }
265    }
266   
 
267  0 toggle private String calcMissing(String str) {
268  0 if (str == null) {
269  0 return "???";
270    }
271  0 if (str.trim().isEmpty()) {
272  0 return "???";
273    }
274  0 return str;
275    }
276   
 
277  0 toggle private String calcDesc(XSAnnotation annotation) {
278  0 if (annotation == null) {
279  0 return null;
280    }
281  0 if (annotation.getAnnotation() == null) {
282  0 return null;
283    }
284  0 return annotation.getAnnotation().toString();
285    }
286   
 
287  0 toggle private void addMessageStructure(String xmlObject, XSElementDecl element) {
288  0 MessageStructure ms = new MessageStructure();
289  0 this.messageStructures.add(ms);
290  0 ms.setXmlObject(xmlObject);
291  0 ms.setShortName(element.getName());
292  0 ms.setName("???");
293  0 ms.setId(xmlObject + "." + ms.getShortName());
294  0 ms.setType(calcType(element, xmlObject + "" + ms.getShortName()));
295  0 ms.setDescription(calcMissing(calcDesc(element.getAnnotation())));
296    // System.out.println("Element " + ms.getId() + " " + ms.getType());
297  0 ms.setRequired(calcRequired(element));
298  0 ms.setCardinality(calcCardinality(element));
299    }
300   
 
301  0 toggle private String calcType(XSElementDecl element, String inLinePrefix) {
302  0 String type = calcType(element.getType(), inLinePrefix);
303  0 if (type != null) {
304  0 return type;
305    }
306  0 return type;
307    }
308   
 
309  0 toggle private String calcType(XSType xsType, String inLinePrefix) {
310  0 if (xsType.isSimpleType()) {
311  0 XSSimpleType st = xsType.asSimpleType();
312  0 return st.getBaseType().getName();
313    // if (st.isRestriction ())
314    // {
315    // XSRestrictionSimpleType res = st.asRestriction ();
316    // return res.getBaseType ().getName ();
317    // }
318    }
319  0 String type = xsType.getName();
320  0 if (type != null) {
321  0 return type;
322    }
323  0 if ((xsType.isComplexType())) {
324  0 XSComplexType ct = xsType.asComplexType();
325  0 String baseType = ct.getBaseType().getName();
326  0 if (baseType.equals("anyType")) {
327  0 baseType = "";
328    }
329  0 String inlineTypeName = inLinePrefix + baseType;
330  0 addComplexType(ct, inlineTypeName);
331  0 return inlineTypeName;
332    }
333  0 throw new IllegalArgumentException("cannot calculate the type of the field " + inLinePrefix);
334    }
335   
 
336  0 toggle private String calcRequired(XSElementDecl element) {
337    // TODO: isNillable seems to ALWAYS be true so... figure out another way
338    // if (element.isNillable()) {
339    // return null;
340    // }
341    // return "Required";
342    // TODO: facets only hold min/maxLength not min/maxOccurs find out where min/maxOccurs is parsed into
343    // String minOccurs = this.getFacetValue(element, "minOccurs");
344    // if (minOccurs == null) {
345    // return "No";
346    // }
347    // if (minOccurs.equals("0")) {
348    // return "No";
349    // }
350    // System.out.println(element.getName() + " has a minOccurs that is " + minOccurs);
351    // return "Required";
352  0 return "???";
353    }
354   
 
355  0 toggle private String calcCardinality(XSElementDecl element) {
356    // if (element.getName().equals ("NoteMessage")) {
357    // System.out.println ("start debugging because NoteMessage has maxOccurs=unbounded");
358    // }
359  0 if (this.getIsRepeated(element)) {
360  0 return "Many";
361    }
362    // TODO: facets only hold min/maxLength not min/maxOccurs find out where min/maxOccurs is parsed into
363    // String maxOccurs = this.getFacetValue(element, "maxOccurs");
364    // if (maxOccurs == null) {
365    // return "One";
366    // }
367    // if (maxOccurs.equals("unbounded")) {
368    // return "Many";
369    // }
370    // System.out.println(element.getName() + " has a maxOccurs that is " + maxOccurs);
371    // return "Many";
372  0 return null;
373    }
374   
 
375  0 toggle private boolean getIsRepeated (XSElementDecl element) {
376  0 XSType type = element.getType();
377  0 if (type == null) {
378  0 return false;
379    }
380  0 if (type.isComplexType()) {
381  0 XSContentType contentType = type.asComplexType().getContentType();
382  0 if (contentType == null) {
383  0 return false;
384    }
385  0 XSParticle particle = contentType.asParticle();
386  0 if (particle == null) {
387  0 return false;
388    }
389  0 particle.isRepeated();
390    }
391    // if (type.isSimpleType())
392  0 return false;
393    }
394   
 
395  0 toggle private String getFacetValue(XSElementDecl element, String name) {
396  0 XSType type = element.getType();
397  0 if (type == null) {
398  0 return null;
399    }
400  0 if (type.isSimpleType()) {
401  0 XSFacet facet = type.asSimpleType().getFacet(name);
402  0 if (facet == null) {
403  0 return null;
404    }
405  0 return facet.getValue().toString();
406    }
407  0 if (type.isComplexType()) {
408  0 XSContentType contentType = type.asComplexType().getContentType();
409  0 if (contentType == null) {
410  0 return null;
411    }
412  0 XSSimpleType simpleType = contentType.asSimpleType();
413  0 if (simpleType == null) {
414  0 return null;
415    }
416  0 XSFacet facet = simpleType.getFacet(name);
417  0 if (facet == null) {
418  0 return null;
419    }
420  0 return facet.getValue().toString();
421    }
422  0 return null;
423    }
424   
425    /**
426    * helper class
427    */
 
428    private static class XsdAnnotationParserFactory implements AnnotationParserFactory {
429   
 
430  0 toggle @Override
431    public AnnotationParser create() {
432  0 return new XsdAnnotationParser();
433    }
434    }
435   
436    /**
437    * helper class
438    */
 
439    private static class XsdAnnotationParser extends AnnotationParser {
440   
441    private StringBuilder documentation = new StringBuilder();
442   
 
443  0 toggle @Override
444    public ContentHandler getContentHandler(AnnotationContext context,
445    String parentElementName,
446    ErrorHandler handler,
447    EntityResolver resolver) {
448  0 return new XsdContentHandler(documentation);
449    }
450   
 
451  0 toggle @Override
452    public Object getResult(Object existing) {
453  0 return documentation.toString().trim();
454    }
455    }
456   
457    /**
458    * helper class
459    */
 
460    private static class XsdContentHandler implements ContentHandler {
461   
462    private StringBuilder documentation;
463   
 
464  0 toggle public XsdContentHandler(StringBuilder documentation) {
465  0 this.documentation = documentation;
466    }
467    private boolean parsingDocumentation = false;
468   
 
469  0 toggle @Override
470    public void characters(char[] ch, int start, int length)
471    throws SAXException {
472  0 if (parsingDocumentation) {
473  0 documentation.append(ch, start, length);
474    }
475    }
476   
 
477  0 toggle @Override
478    public void endElement(String uri, String localName, String name)
479    throws SAXException {
480  0 if (localName.equals("documentation")) {
481  0 parsingDocumentation = false;
482    }
483    }
484   
 
485  0 toggle @Override
486    public void startElement(String uri, String localName, String name,
487    Attributes atts) throws SAXException {
488  0 if (localName.equals("documentation")) {
489  0 parsingDocumentation = true;
490    }
491    }
492   
 
493  0 toggle @Override
494    public void endDocument() throws SAXException {
495    // do nothing
496    }
497   
 
498  0 toggle @Override
499    public void endPrefixMapping(String prefix) throws SAXException {
500    // do nothing
501    }
502   
 
503  0 toggle @Override
504    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
505    // do nothing
506    }
507   
 
508  0 toggle @Override
509    public void processingInstruction(String target, String data) throws SAXException {
510    // do nothing
511    }
512   
 
513  0 toggle @Override
514    public void setDocumentLocator(Locator locator) {
515    // do nothing
516    }
517   
 
518  0 toggle @Override
519    public void skippedEntity(String name) throws SAXException {
520    // do nothing
521    }
522   
 
523  0 toggle @Override
524    public void startDocument() throws SAXException {
525    // do nothing
526    }
527   
 
528  0 toggle @Override
529    public void startPrefixMapping(String prefix, String uri) throws SAXException {
530    // do nothing
531    }
532    }
533    }