View Javadoc

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.thoughtworks.qdox.JavaDocBuilder;
19  import com.thoughtworks.qdox.model.Annotation;
20  import com.thoughtworks.qdox.model.DefaultDocletTagFactory;
21  import com.thoughtworks.qdox.model.DocletTag;
22  import com.thoughtworks.qdox.model.JavaClass;
23  import com.thoughtworks.qdox.model.JavaField;
24  import com.thoughtworks.qdox.model.JavaMethod;
25  import com.thoughtworks.qdox.model.JavaParameter;
26  import com.thoughtworks.qdox.model.Type;
27  import com.thoughtworks.qdox.model.annotation.AnnotationValue;
28  import java.io.File;
29  import java.util.ArrayList;
30  import java.util.Arrays;
31  import java.util.Collection;
32  import java.util.Collections;
33  import java.util.Date;
34  import java.util.LinkedHashMap;
35  import java.util.LinkedHashSet;
36  import java.util.List;
37  import java.util.Map;
38  import java.util.Set;
39  
40  import org.kuali.student.contract.model.MessageStructure;
41  import org.kuali.student.contract.model.Service;
42  import org.kuali.student.contract.model.ServiceContractModel;
43  import org.kuali.student.contract.model.ServiceMethod;
44  import org.kuali.student.contract.model.ServiceMethodError;
45  import org.kuali.student.contract.model.ServiceMethodParameter;
46  import org.kuali.student.contract.model.ServiceMethodReturnValue;
47  import org.kuali.student.contract.model.XmlType;
48  
49  /**
50   *
51   * @author nwright
52   */
53  public class ServiceContractModelQDoxLoader implements
54          ServiceContractModel {
55  
56      private static final String LOCALE_KEY_LIST = "LocaleKeyList";
57      private static final String MESSAGE_GROUP_KEY_LIST = "MessageGroupKeyList";
58      private static final JavaClass STRING_JAVA_CLASS = new JavaClass(
59              "java.lang.String");
60      private List<String> sourceDirectories = null;
61      private List<Service> services = null;
62      private List<ServiceMethod> serviceMethods = null;
63      private Map<String, XmlType> xmlTypeMap = null;
64      private List<MessageStructure> messageStructures;
65      private boolean validateKualiStudent = true;
66  
67      public ServiceContractModelQDoxLoader(List<String> sourceDirectories) {
68          this.sourceDirectories = sourceDirectories;
69      }
70  
71      public ServiceContractModelQDoxLoader(List<String> sourceDirectories, boolean validateKualiStudent) {
72          this.sourceDirectories = sourceDirectories;
73          this.setValidateKualiStudent(validateKualiStudent);
74      }
75  
76      public boolean isValidateKualiStudent() {
77          return validateKualiStudent;
78      }
79  
80      public void setValidateKualiStudent(boolean validateKualiStudent) {
81          this.validateKualiStudent = validateKualiStudent;
82      }
83  
84      @Override
85      public List<ServiceMethod> getServiceMethods() {
86          if (this.serviceMethods == null) {
87              this.parse();
88          }
89          return this.serviceMethods;
90      }
91  
92      @Override
93      public List<String> getSourceNames() {
94          List<String> list = new ArrayList(this.sourceDirectories.size());
95          for (String javaFile : this.sourceDirectories) {
96              list.add(javaFile);
97          }
98          return list;
99      }
100 
101     @Override
102     public List<Service> getServices() {
103         if (services == null) {
104             this.parse();
105         }
106         return services;
107     }
108 
109     @Override
110     public List<XmlType> getXmlTypes() {
111         if (xmlTypeMap == null) {
112             this.parse();
113         }
114         return new ArrayList(xmlTypeMap.values());
115     }
116 
117     @Override
118     public List<MessageStructure> getMessageStructures() {
119         if (messageStructures == null) {
120             this.parse();
121         }
122         return this.messageStructures;
123     }
124 
125     private String dump(DocletTag tag) {
126         if (tag == null) {
127             return null;
128         }
129         StringBuilder bldr = new StringBuilder();
130         bldr.append(tag.getName());
131         bldr.append("=");
132         if (tag.getNamedParameterMap() == null
133                 || tag.getNamedParameterMap().isEmpty()) {
134             bldr.append(tag.getValue());
135         } else {
136             for (Object key : tag.getNamedParameterMap().keySet()) {
137                 Object value = tag.getNamedParameterMap().get(key);
138                 bldr.append("(");
139                 bldr.append(key);
140                 bldr.append("=");
141                 bldr.append(value);
142                 bldr.append(")");
143             }
144         }
145         return bldr.toString();
146     }
147 
148     private void checkIfExists(String sourceDirectory) {
149         File file = new File(sourceDirectory);
150         if (!file.isDirectory()) {
151             throw new IllegalArgumentException(sourceDirectory + " is not a directory on disk");
152         }
153     }
154 
155     private void parse() {
156 //  System.out.println ("ServiceContractModelQDoxLoader: Starting parse");
157         services = new ArrayList();
158         serviceMethods = new ArrayList();
159         xmlTypeMap = new LinkedHashMap();
160         messageStructures = new ArrayList();
161         DefaultDocletTagFactory dtf = new DefaultDocletTagFactory();
162         JavaDocBuilder builder = new JavaDocBuilder(dtf);
163         for (String sourceDirectory : sourceDirectories) {
164             checkIfExists(sourceDirectory);
165             builder.addSourceTree(new File(sourceDirectory));
166         }
167         List<JavaClass> sortedClasses = Arrays.asList(builder.getClasses());
168         Collections.sort(sortedClasses);
169         for (JavaClass javaClass : sortedClasses) {
170             if (!this.isServiceToProcess(javaClass)) {
171                 continue;
172             }
173 //   System.out.println ("processing service=" + javaClass.getName ());
174             Service service = new Service();
175             services.add(service);
176             service.setKey(javaClass.getName().substring(0, javaClass.getName().length()
177                     - "Service".length()));
178             service.setName(javaClass.getName());
179             service.setComments(this.calcComment(javaClass));
180             service.setUrl(this.calcServiceUrl(javaClass));
181             service.setVersion(this.calcVersion(javaClass));
182             service.setStatus("???");
183             service.setIncludedServices(calcIncludedServices(javaClass));
184             service.setImplProject(javaClass.getPackageName());
185 
186 //   for (DocletTag tag : javaClass.getTags ())
187 //   {
188 //    System.out.println ("ServiceContractModelQDoxLoader: Class: "
189 //                        + javaClass.getName () + " has tag=" + dump (
190 //      tag));
191 //   }
192             for (JavaMethod javaMethod : javaClass.getMethods()) {
193 
194                 ServiceMethod serviceMethod = new ServiceMethod();
195                 serviceMethods.add(serviceMethod);
196                 serviceMethod.setService(service.getKey());
197                 serviceMethod.setName(javaMethod.getName());
198                 serviceMethod.setDescription(calcMissing(javaMethod.getComment()));
199                 serviceMethod.setParameters(new ArrayList());
200 //    for (DocletTag tag : javaMethod.getTags ())
201 //    {
202 //     System.out.println ("ServiceContractModelQDoxLoader: Method: "
203 //                         + service.getName () + "."
204 //                         + javaMethod.getName ()
205 //                         + " has tag=" + dump (tag));
206 //    }
207                 // parameters
208                 for (JavaParameter parameter : javaMethod.getParameters()) {
209                     ServiceMethodParameter param = new ServiceMethodParameter();
210                     serviceMethod.getParameters().add(param);
211                     param.setName(parameter.getName());
212                     param.setType(calcType(parameter.getType()));
213                     param.setDescription(calcMissing(
214                             calcParameterDescription(javaMethod,
215                             param.getName())));
216                     addXmlTypeAndMessageStructure(calcRealJavaClass(parameter.getType()),
217                             serviceMethod.getService());
218                 }
219                 // errors
220                 serviceMethod.setErrors(new ArrayList());
221                 for (Type exception : javaMethod.getExceptions()) {
222                     ServiceMethodError error = new ServiceMethodError();
223                     error.setType(this.calcType(exception.getJavaClass()));
224                     error.setDescription(calcMissing(
225                             calcExceptionDescription(javaMethod,
226                             error.getType())));
227                     error.setPackageName(exception.getJavaClass().getPackageName());
228                     error.setClassName(exception.getJavaClass().getName());
229                     serviceMethod.getErrors().add(error);
230                 }
231                 // return values
232                 ServiceMethodReturnValue rv = new ServiceMethodReturnValue();
233                 serviceMethod.setReturnValue(rv);
234                 Type returnType = null;
235                 try {
236                     returnType = javaMethod.getReturnType();
237                 } catch (NullPointerException ex) {
238                     System.out.println("Nullpinter getting return type: " + javaMethod.getCallSignature());
239                     returnType = null;
240                 }
241 
242                 rv.setType(calcType(returnType));
243                 rv.setDescription(calcMissing(this.calcReturnDescription(javaMethod)));
244                 if (returnType != null) {
245                     addXmlTypeAndMessageStructure(calcRealJavaClass(returnType),
246                             serviceMethod.getService());
247                 }
248             }
249         }
250     }
251 
252     private boolean isServiceToProcess(JavaClass javaClass) {
253 //  System.out.println ("looking if javaClass is a service to process=" + javaClass.getName () + "=" + javaClass.getPackageName ());
254         if (!javaClass.getName().endsWith("Service")) {
255             return false;
256         }
257         if (javaClass.getPackageName().contains(".old.")) {
258 
259             return false;
260         }
261         if (javaClass.getPackageName().endsWith(".old")) {
262             return false;
263         }
264         for (Annotation annotation : javaClass.getAnnotations()) {
265 //   System.out.println ("looking for webservice tag=" + annotation.getType ().getJavaClass ().getName ());
266             if (annotation.getType().getJavaClass().getName().equals("WebService")) {
267 //    System.out.println ("Processing web service=" + javaClass.getPackageName ()
268 //                        + "." + javaClass.getName ());
269                 return true;
270             }
271         }
272         // This includes RICE's business object services even though they are not web services
273         // because often they are the only real service they have exposed and it helps to document
274         // them to see what the data really is like
275         if (javaClass.getName().endsWith("BoService")) {
276             return true;
277         }
278 //  System.out.println ("skipping service because it is not a web service="
279 //                      + javaClass.getPackageName () + "." + javaClass.getName ());
280         return false;
281     }
282 
283     private List<String> calcIncludedServices(JavaClass javaClass) {
284         List<String> includedServices = new ArrayList<String>();
285         for (JavaClass interfaceClass : javaClass.getImplementedInterfaces()) {
286 //            System.out.println("ServiceContractModelQDoxLoader:" + javaClass.getName()
287 //                    + " implements " + interfaceClass.getName());
288             includedServices.add(interfaceClass.getName());
289         }
290         return includedServices;
291     }
292 
293     private String calcParameterDescription(JavaMethod method,
294             String parameterName) {
295         for (DocletTag tag : method.getTags()) {
296             if (tag.getName().equals("param")) {
297                 if (tag.getValue().startsWith(parameterName + " ")) {
298                     return tag.getValue().substring(parameterName.length() + 1);
299                 }
300             }
301         }
302         return null;
303     }
304 
305     private String calcExceptionDescription(JavaMethod serviceMethod,
306             String exceptionType) {
307         for (DocletTag tag : serviceMethod.getTags()) {
308             if (tag.getName().equals("throws")) {
309                 if (tag.getValue().startsWith(exceptionType + " ")) {
310                     return tag.getValue().substring(exceptionType.length() + 1);
311                 }
312             }
313         }
314         return null;
315     }
316 
317     private String calcReturnDescription(JavaMethod serviceMethod) {
318         for (DocletTag tag : serviceMethod.getTags()) {
319             if (tag.getName().equals("return")) {
320                 return tag.getValue();
321             }
322         }
323         return null;
324     }
325 
326     private String calcServiceUrl(JavaClass serviceClass) {
327         for (DocletTag tag : serviceClass.getTags()) {
328             if (tag.getName().equals("See")) {
329                 return tag.getValue();
330             }
331         }
332         return null;
333     }
334 
335     private void addXmlTypeAndMessageStructure(JavaClass messageStructureJavaClass,
336             String serviceKey) {
337         String name = calcType(messageStructureJavaClass);
338         XmlType xmlType = xmlTypeMap.get(name);
339         if (xmlType == null) {
340             xmlType = new XmlType();
341             xmlTypeMap.put(name, xmlType);
342             xmlType.setName(name);
343             xmlType.setDesc(this.calcMessageStructureDesc(messageStructureJavaClass));
344             xmlType.setService(serviceKey);
345             xmlType.setVersion("IGNORE -- SAME AS SERVICE");
346             xmlType.setPrimitive(calcPrimitive(messageStructureJavaClass));
347             xmlType.setJavaPackage(calcJavaPackage(messageStructureJavaClass));
348             if (xmlType.getPrimitive().equals(XmlType.COMPLEX)) {
349                 addMessageStructure(messageStructureJavaClass, serviceKey);
350             }
351         } else {
352             addServiceToList(xmlType, serviceKey);
353         }
354     }
355 
356     private String calcJavaPackage(JavaClass javaClass) {
357         String packageName = javaClass.getPackageName();
358         return packageName;
359     }
360 
361     private String calcMessageStructureDesc(JavaClass javaClass) {
362         {
363             String desc = javaClass.getComment();
364             if (desc != null) {
365                 if (!desc.isEmpty()) {
366                     return desc;
367                 }
368             }
369             JavaClass infcClass = this.getMatchingInfc(javaClass);
370             if (infcClass == null) {
371                 return null;
372             }
373             return infcClass.getComment();
374         }
375     }
376 
377     private JavaClass getMatchingInfc(JavaClass javaClass) {
378         // ks uses this pattern
379         String nameInfc = javaClass.getName();
380         if (nameInfc.endsWith("Info")) {
381             nameInfc = nameInfc.substring(0, nameInfc.length() - "Info".length())
382                     + "Infc";
383         }
384         String nameWithOutInfo = javaClass.getName();
385         // rice uses this pattern
386         if (nameWithOutInfo.endsWith("Info")) {
387             nameWithOutInfo = nameWithOutInfo.substring(0, nameWithOutInfo.length()
388                     - "Info".length());
389         }
390         for (JavaClass infc : javaClass.getImplementedInterfaces()) {
391             if (infc.getName().equals(nameInfc)) {
392 //                System.out.println("found matching interface " + infc.getName());
393                 return infc;
394             }
395             if (infc.getName().equals(nameWithOutInfo)) {
396                 return infc;
397             }
398         }
399         return null;
400     }
401 
402     private String calcPrimitive(JavaClass javaClass) {
403         if (this.isComplex(javaClass)) {
404             return XmlType.COMPLEX;
405         }
406         return "Primitive";
407     }
408 
409     private String initLower(String str) {
410         if (str == null) {
411             return null;
412         }
413         if (str.length() == 0) {
414             return str;
415         }
416         if (str.length() == 1) {
417             return str.toLowerCase();
418         }
419         return str.substring(0, 1).toLowerCase() + str.substring(1);
420     }
421 
422     private String initUpper(String str) {
423         if (str == null) {
424             return null;
425         }
426         if (str.length() == 0) {
427             return str;
428         }
429         if (str.length() == 1) {
430             return str.toUpperCase();
431         }
432         return str.substring(0, 1).toUpperCase() + str.substring(1);
433     }
434 
435     private Set<String> getShortNames(JavaClass messageStructureJavaClass) {
436         Set<String> fields = getFieldsUsingPropOrder(messageStructureJavaClass);
437         if (fields != null) {
438             return fields;
439         }
440         fields = new LinkedHashSet();
441         for (JavaMethod method : messageStructureJavaClass.getMethods(true)) {
442             if (isSetterMethodToProcess(method, messageStructureJavaClass.getName())) {
443                 String shortName = this.calcShortNameFromSetter(method);
444                 fields.add(shortName);
445                 continue;
446             }
447             if (isGetterMethodToProcess(method, messageStructureJavaClass.getName())) {
448                 String shortName = this.calcShortNameFromGetter(method);
449                 fields.add(shortName);
450                 continue;
451             }
452         }
453         return fields;
454     }
455 
456     private Set<String> getFieldsUsingPropOrder(
457             JavaClass messageStructureJavaClass) {
458         for (Annotation annotation : messageStructureJavaClass.getAnnotations()) {
459             if (annotation.getType().getJavaClass().getName().equals("XmlType")) {
460                 AnnotationValue propOrderParam = annotation.getProperty("propOrder");
461                 if (propOrderParam == null) {
462                     continue;
463                 }
464                 Object propOrderValue = propOrderParam.getParameterValue();
465                 if (!(propOrderValue instanceof List)) {
466                     continue;
467                 }
468                 Set<String> fields = new LinkedHashSet();
469                 for (Object value : (List) propOrderValue) {
470                     if (value instanceof String) {
471                         String shortName = (String) value;
472                         shortName = this.stripQuotes(shortName);
473                         if (shortName.contains(".Elements.")) {
474                             String newShortName = getShortNameFromElements(shortName, messageStructureJavaClass);
475                             if (newShortName == null) {
476                                 continue;
477                             }
478                             shortName = newShortName;
479                         } else if (shortName.startsWith("CoreConstants.CommonElements.")) {
480                             String newShortName = getCoreConstants(shortName);
481                             if (newShortName == null) {
482                                 continue;
483                             }
484                             shortName = newShortName;
485                         }
486                         if (shortName.equals("_futureElements")) {
487                             continue;
488                         }
489                         shortName = this.initUpper(shortName);
490                         fields.add(shortName);
491                     }
492                 }
493                 return fields;
494             }
495         }
496         return null;
497     }
498 
499     private String getShortNameFromElements(String shortName, JavaClass messageStructureJavaClass) {
500         JavaClass elementsJavaClass = messageStructureJavaClass.getNestedClassByName("Elements");
501         if (elementsJavaClass == null) {
502             return null;
503         }
504         String fieldName = shortName.substring(shortName.indexOf(".Elements.") + ".Elements.".length());
505         JavaField field = elementsJavaClass.getFieldByName(fieldName);
506         String initExpr = field.getInitializationExpression();
507         return stripQuotes(initExpr);
508     }
509 
510     private String getCoreConstants(String shortName) {
511         if (shortName.endsWith("VERSION_NUMBER")) {
512             return "versionNumber";
513         }
514         if (shortName.endsWith("OBJECT_ID")) {
515             return "objectId";
516         }
517         if (shortName.endsWith("ACTIVE")) {
518             return "active";
519         }
520         if (shortName.endsWith("ACTIVE_FROM_DATE")) {
521             return "activeFromDate";
522         }
523         if (shortName.endsWith("ACTIVE_TO_DATE")) {
524             return "activeToDate";
525         }
526         if (shortName.endsWith("ATTRIBUTES")) {
527             return "attributes";
528         }
529         if (shortName.endsWith("FUTURE_ELEMENTS")) {
530             return "_futureElements";
531         }
532         throw new RuntimeException("Unknown shortName " + shortName);
533     }
534 
535     private void addMessageStructure(JavaClass messageStructureJavaClass,
536             String serviceKey) {
537         Set<JavaClass> subObjectsToAdd = new LinkedHashSet();
538         for (String shortName : this.getShortNames(messageStructureJavaClass)) {
539             JavaMethod setterMethod = findSetterMethod(messageStructureJavaClass,
540                     shortName);
541             JavaMethod getterMethod = findGetterMethod(messageStructureJavaClass,
542                     shortName);
543             if (getterMethod == null) {
544                 if (this.validateKualiStudent) {
545                     throw new IllegalArgumentException("shortName has no corresponding getter method: "
546                             + messageStructureJavaClass.getFullyQualifiedName()
547                             + "." + shortName);
548                 }
549             }
550             JavaField beanField = this.findField(messageStructureJavaClass,
551                     shortName, setterMethod);
552             if (beanField == null) {
553                 String accessorType = getAccessorType(getterMethod);
554                 if ("XmlAccessType.FIELD".equals(accessorType)) {
555                     throw new IllegalArgumentException("Setter method has no corresponding bean field: "
556                             + messageStructureJavaClass.getName()
557                             + "." + getterMethod.getName());
558                 }
559             }
560             // overide the shortName if the bean field has an XmlAttribute name=xxx
561             // this catches the key=id switch
562             if (beanField != null) {
563                 for (Annotation annotation : beanField.getAnnotations()) {
564                     if (annotation.getType().getJavaClass().getName().equals("XmlAttribute")) {
565                         Object nameValue = annotation.getNamedParameter("name");
566                         if (nameValue != null) {
567                             shortName = stripQuotes(nameValue.toString());
568                         }
569                     }
570                 }
571             }
572             shortName = initLower(shortName);
573             MessageStructure ms = new MessageStructure();
574             messageStructures.add(ms);
575             ms.setXmlObject(messageStructureJavaClass.getName());
576             ms.setShortName(shortName);
577             ms.setId(ms.getXmlObject() + "." + ms.getShortName());
578             ms.setName(calcMissing(calcName(messageStructureJavaClass, getterMethod, setterMethod,
579                     beanField, shortName)));
580             ms.setType(calcType(messageStructureJavaClass, getterMethod, setterMethod, beanField, shortName));
581             if (ms.getType().equals("Object")) {
582                 System.out.println("WARNING " + ms.getId()
583                         + " has Object as it's type ==> Changing to String");
584                 ms.setType("String");
585             } else if (ms.getType().equals("ObjectList")) {
586                 System.out.println(
587                         "WARNING " + ms.getId()
588                         + " has a list of Objects as it's type ==> Changing to List of String");
589                 ms.setType("StringList");
590             }
591             ms.setXmlAttribute(this.calcXmlAttribute(beanField));
592             ms.setRequired(calcRequired(getterMethod, setterMethod, beanField));
593             ms.setReadOnly(calcReadOnly(getterMethod, setterMethod, beanField));
594             ms.setCardinality(this.calcCardinality(messageStructureJavaClass, getterMethod, setterMethod, beanField, shortName));
595             ms.setDescription(calcMissing(calcDescription(messageStructureJavaClass, getterMethod, setterMethod,
596                     beanField)));
597             ms.setImplNotes(calcImplementationNotes(getterMethod, setterMethod, beanField));
598             ms.setStatus("???");
599 //            if (ms.getId().equals("AcademicCalendarInfo.typeKey")) {
600 //                System.out.println("debug from here");
601 //            }
602             ms.setOverriden(this.calcOverridden(messageStructureJavaClass, getterMethod));
603             JavaClass subObjToAdd = this.calcRealJavaClassOfGetterReturn(getterMethod);
604             if (subObjToAdd != null) {
605 //                if (!subObjToAdd.isEnum()) {
606                     if (!subObjToAdd.getName().equals("Object")) {
607                         if (!subObjToAdd.getName().equals("LocaleKeyList")) {
608                             if (!subObjToAdd.getName().equals("MessageGroupKeyList")) {
609                                 subObjectsToAdd.add(subObjToAdd);
610                             }
611                         }
612                     }
613 //                }
614             }
615         }
616         // now add all it's complex sub-objects if they haven't already been added
617         for (JavaClass subObjectToAdd : subObjectsToAdd) {
618             XmlType xmlType = xmlTypeMap.get(calcType(subObjectToAdd));
619             if (xmlType == null) {
620                 addXmlTypeAndMessageStructure(subObjectToAdd, serviceKey);
621             } else {
622                 addServiceToList(xmlType, serviceKey);
623             }
624         }
625         return;
626     }
627 
628     private boolean calcOverridden(JavaClass mainClass, JavaMethod getterMethod) {
629         if (getterMethod == null) {
630             return false;
631         }
632         JavaMethod infcGetter = null;
633         if (getterMethod.getParentClass().isInterface()) {
634             infcGetter = getterMethod;
635         }
636         if (infcGetter == null) {
637             infcGetter = findInterfaceMethod(mainClass, getterMethod);
638         }
639         if (infcGetter == null) {
640             return false;
641         }
642         Annotation annotation = this.getAnnotation(infcGetter, null, null, "Override");
643         if (annotation != null) {
644             return true;
645         }
646         return false;
647     }
648 
649     private String calcComment(JavaClass javaClass) {
650         return this.calcComment(javaClass.getComment());
651     }
652 
653     private String calcComment(String comment) {
654         return this.parseCommentVersion(comment)[0];
655     }
656 
657     private String calcVersion(JavaClass javaClass) {
658         DocletTag tag = javaClass.getTagByName("version", true);
659         if (tag != null) {
660             return tag.getValue();
661         }
662         return this.calcVersion(javaClass.getComment());
663     }
664 
665     private String calcVersion(String comment) {
666         return this.parseCommentVersion(comment)[1];
667     }
668 
669     private String[] parseCommentVersion(String commentVersion) {
670         String[] parsed = new String[2];
671         if (commentVersion == null) {
672             return parsed;
673         }
674         commentVersion = commentVersion.trim();
675         int i = commentVersion.toLowerCase().indexOf("\nversion:");
676         if (i == -1) {
677             parsed[0] = commentVersion;
678             return parsed;
679         }
680         parsed[1] = commentVersion.substring(i + "\nversion:".length()).trim();
681         parsed[0] = commentVersion.substring(0, i).trim();
682 
683         return parsed;
684     }
685 
686     private Annotation getAnnotation(JavaMethod getterMethod,
687             JavaMethod setterMethod, JavaField beanField, String type) {
688         if (beanField != null) {
689 
690             for (Annotation annotation : beanField.getAnnotations()) {
691                 if (annotation.getType().getJavaClass().getName().equals(type)) {
692                     return annotation;
693                 }
694             }
695         }
696         if (getterMethod != null) {
697 
698             for (Annotation annotation : getterMethod.getAnnotations()) {
699                 if (annotation.getType().getJavaClass().getName().equals(type)) {
700                     return annotation;
701                 }
702             }
703         }
704         if (setterMethod != null) {
705 
706             for (Annotation annotation : setterMethod.getAnnotations()) {
707                 if (annotation.getType().getJavaClass().getName().equals(type)) {
708                     return annotation;
709                 }
710             }
711         }
712         return null;
713     }
714 
715     private String calcRequired(JavaMethod getterMethod,
716             JavaMethod setterMethod, JavaField beanField) {
717         Annotation annotation = this.getAnnotation(getterMethod, setterMethod, beanField, "XmlElement");
718         if (annotation == null) {
719             annotation = this.getAnnotation(getterMethod, setterMethod, beanField, "XmlAttribute");
720         }
721         if (annotation != null) {
722             Object required = annotation.getNamedParameter("required");
723             if (required != null) {
724                 if (required.toString().equalsIgnoreCase("true")) {
725                     return "Required";
726                 }
727             }
728         }
729         if (getterMethod != null) {
730             DocletTag tag = getterMethod.getTagByName("required", true);
731             if (tag != null) {
732                 if (tag.getValue() == null) {
733                     return "Required";
734                 }
735                 String required = "Required " + tag.getValue();
736                 return required.trim();
737             }
738         }
739         return null;
740     }
741 
742     private String calcReadOnly(JavaMethod getterMethod,
743             JavaMethod setterMethod, JavaField beanField) {
744         if (getterMethod != null) {
745             DocletTag tag = getterMethod.getTagByName("readOnly", true);
746             if (tag != null) {
747                 if (tag.getValue() == null) {
748                     return "Read only";
749                 }
750                 String readOnly = "Read only " + tag.getValue();
751                 return readOnly.trim();
752             }
753         }
754         return null;
755     }
756 
757     private String calcImplementationNotes(JavaMethod getterMethod,
758             JavaMethod setterMethod, JavaField beanField) {
759         if (getterMethod != null) {
760             DocletTag tag = getterMethod.getTagByName("impl", true);
761             if (tag != null) {
762                 return tag.getValue();
763             }
764         }
765         return null;
766     }
767 
768     private String calcNameFromShortName(String shortName) {
769         StringBuilder bldr = new StringBuilder(shortName.length() + 3);
770         char c = shortName.charAt(0);
771         bldr.append(Character.toUpperCase(c));
772         boolean lastWasUpper = true;
773         for (int i = 1; i < shortName.length(); i++) {
774             c = shortName.charAt(i);
775             if (Character.isUpperCase(c)) {
776                 if (!lastWasUpper) {
777                     bldr.append(" ");
778                 }
779             } else {
780                 lastWasUpper = false;
781             }
782             bldr.append(c);
783         }
784         return bldr.toString();
785     }
786 
787     private String calcName(JavaClass mainClass, JavaMethod getterMethod,
788             JavaMethod setterMethod, JavaField beanField, String shortName) {
789         String name = this.calcNameFromTag(getterMethod, setterMethod, beanField);
790         if (name != null) {
791             return name;
792         }
793         name = this.calcNameFromNameEmbeddedInDescription(mainClass, getterMethod, setterMethod, beanField);
794         if (name != null) {
795             return name;
796         }
797         return this.calcNameFromShortName(shortName);
798     }
799 
800     private String calcNameFromTag(JavaMethod getterMethod,
801             JavaMethod setterMethod, JavaField beanField) {
802         if (getterMethod != null) {
803             DocletTag tag = getterMethod.getTagByName("name", true);
804             if (tag != null) {
805                 return tag.getValue();
806             }
807         }
808         return null;
809     }
810 
811     private String calcNameFromNameEmbeddedInDescription(JavaClass mainClass, JavaMethod getterMethod,
812             JavaMethod setterMethod, JavaField beanField) {
813         String nameDesc = this.calcMethodComment(mainClass, getterMethod, setterMethod,
814                 beanField);
815         String[] parsed = parseNameDesc(nameDesc);
816         return parsed[0];
817     }
818 
819     private String[] parseNameDesc(String nameDesc) {
820         String[] parsed = new String[2];
821         if (nameDesc == null) {
822             return parsed;
823         }
824         nameDesc = nameDesc.trim();
825         if (!nameDesc.startsWith("Name:")) {
826             parsed[1] = nameDesc;
827             return parsed;
828         }
829         nameDesc = nameDesc.substring("Name:".length()).trim();
830         int i = nameDesc.indexOf("\n");
831         if (i == -1) {
832             parsed[0] = nameDesc.trim();
833             return parsed;
834         }
835         parsed[0] = nameDesc.substring(0, i).trim();
836         parsed[1] = nameDesc.substring(i).trim();
837         return parsed;
838     }
839 
840     private String calcDescription(JavaClass mainClass, JavaMethod getterMethod,
841             JavaMethod setterMethod, JavaField beanField) {
842         String nameDesc = this.calcMethodComment(mainClass, getterMethod, setterMethod,
843                 beanField);
844         String[] parsed = parseNameDesc(nameDesc);
845         return parsed[1];
846     }
847 
848     private String calcMethodComment(JavaClass mainClass, JavaMethod getterMethod,
849             JavaMethod setterMethod,
850             JavaField beanField) {
851         String desc = null;
852         if (getterMethod != null) {
853             desc = getterMethod.getComment();
854             if (isCommentNotEmpty(desc)) {
855                 return desc;
856             }
857         }
858         if (setterMethod != null) {
859             desc = setterMethod.getComment();
860             if (isCommentNotEmpty(desc)) {
861                 return desc;
862             }
863         }
864         if (beanField != null) {
865             desc = beanField.getComment();
866             if (isCommentNotEmpty(desc)) {
867                 return desc;
868             }
869         }
870         desc = calcMethodCommentRecursively(mainClass, getterMethod);
871         if (isCommentNotEmpty(desc)) {
872             return desc;
873         }
874         desc = calcMethodCommentRecursively(mainClass, setterMethod);
875         if (isCommentNotEmpty(desc)) {
876             return desc;
877         }
878         return null;
879     }
880 
881     private String calcMethodCommentRecursively(JavaClass mainClass, JavaMethod method) {
882         if (method == null) {
883             return null;
884         }
885         String desc = method.getComment();
886         if (isCommentNotEmpty(desc)) {
887             return desc;
888         }
889         JavaMethod infcMethod = findInterfaceMethod(mainClass, method);
890         if (infcMethod != null) {
891             desc = infcMethod.getComment();
892             if (isCommentNotEmpty(desc)) {
893                 return desc;
894             }
895         }
896         JavaMethod superMethod = findSuperMethod(method);
897         if (superMethod != null) {
898             desc = superMethod.getComment();
899             if (isCommentNotEmpty(desc)) {
900                 return desc;
901             }
902         }
903         return null;
904     }
905 
906     private JavaMethod findSuperMethod(JavaMethod method) {
907 //        System.out.println("Searching for super method for "
908 //                + method.getParentClass().getName() + "."
909 //                + method.getCallSignature());
910         for (JavaMethod superMethod : method.getParentClass().getMethods(true)) {
911             if (method.equals(superMethod)) {
912                 continue;
913             }
914             if (method.getCallSignature().equals(superMethod.getCallSignature())) {
915                 return superMethod;
916             }
917         }
918         return null;
919     }
920 
921     private JavaMethod findInterfaceMethod(JavaClass mainClass, JavaMethod method) {
922         String callSig = method.getCallSignature();
923         JavaClass classToSearch = mainClass;
924 //        log ("Searching mainClass " + classToSearch.getName() + " for " + callSig, callSig);
925         while (true) {
926             for (JavaClass infcClass : classToSearch.getImplementedInterfaces()) {
927                 JavaMethod meth = this.findMethodOnInterfaceRecursively(infcClass, callSig);
928                 if (meth != null) {
929 //                    recursionCntr = 0;
930                     return meth;
931                 }
932             }
933             JavaClass superClass = classToSearch.getSuperJavaClass();
934             if (superClass == null) {
935 //                recursionCntr = 0;                
936 //                log ("Did not find " + callSig + " on " + mainClass, callSig); 
937                 return null;
938             }
939             classToSearch = superClass;
940 //            log ("Searching superClass " + classToSearch.getName() + " for " + callSig, callSig);                
941         }
942     }
943 
944 //    private void log (String message, String callSig) {
945 //        if (callSig.equalsIgnoreCase("getTypeKey()")) {
946 //            for (int i = 0; i < this.recursionCntr; i++) {
947 //                System.out.print (" ");
948 //            }
949 //            System.out.println (message);
950 //        }
951 //    }
952 //    private int recursionCntr = 0;
953     private JavaMethod findMethodOnInterfaceRecursively(JavaClass infcClass, String callSig) {
954 //        recursionCntr++;
955 //        log ("Searching interface " + infcClass.getName() + " for " + callSig, callSig);
956         for (JavaMethod infcMethod : infcClass.getMethods()) {
957             if (callSig.equals(infcMethod.getCallSignature())) {
958 //                log (callSig + " found on " + infcClass.getName() + "!!!!!!!!!!!!!!!!", callSig); 
959 //                recursionCntr--;
960                 return infcMethod;
961             }
962         }
963         for (JavaClass subInfc : infcClass.getImplementedInterfaces()) {
964 //            log ("Searching  sub-interface " + subInfc.getName() + " for " + callSig, callSig);
965             JavaMethod infcMethod = findMethodOnInterfaceRecursively(subInfc, callSig);
966             if (infcMethod != null) {
967 //                recursionCntr--;
968                 return infcMethod;
969             }
970         }
971 //        log (callSig + " not found on " + infcClass.getName(), callSig);
972 //        this.recursionCntr--;
973         return null;
974     }
975 
976     private boolean isCommentNotEmpty(String desc) {
977         if (desc == null) {
978             return false;
979         }
980         if (desc.trim().isEmpty()) {
981             return false;
982         }
983         if (desc.contains("@inheritDoc")) {
984             return false;
985         }
986         return true;
987     }
988 
989     private String getAccessorType(JavaMethod method) {
990         String accessorType = getAccessorType(method.getAnnotations());
991         if (accessorType != null) {
992             return accessorType;
993         }
994         accessorType = getAccessorType(method.getParentClass().getAnnotations());
995         return accessorType;
996     }
997 
998     private String getAccessorType(Annotation[] annotations) {
999         for (Annotation annotation : annotations) {
1000             if (annotation.getType().getJavaClass().getName().equals(
1001                     "XmlAccessorType")) {
1002 //    System.out.println ("Looking for XmlAccessorType annotation = "
1003 //                        + annotation.getParameterValue ());
1004                 return annotation.getParameterValue().toString();
1005             }
1006         }
1007         return null;
1008     }
1009 
1010     private String stripQuotes(String str) {
1011         if (str.startsWith("\"")) {
1012             str = str.substring(1);
1013         }
1014         if (str.endsWith("\"")) {
1015             str = str.substring(0, str.length() - 1);
1016         }
1017         return str;
1018     }
1019 
1020     private String calcMissing(String str) {
1021         if (str == null) {
1022             return "???";
1023         }
1024         if (str.trim().isEmpty()) {
1025             return "???";
1026         }
1027         return str;
1028     }
1029 
1030     private void addServiceToList(XmlType xmlType, String serviceKey) {
1031         if (!xmlType.getService().contains(serviceKey)) {
1032             xmlType.setService(xmlType.getService() + ", " + serviceKey);
1033         }
1034     }
1035 
1036     private String calcXmlAttribute(JavaField beanField) {
1037         if (beanField == null) {
1038             // TODO: worry about checking for this annotation on the method for non-field based AccessorTypes
1039             return "No";
1040         }
1041         for (Annotation annotation : beanField.getAnnotations()) {
1042             if (annotation.getType().getJavaClass().getName().equals("XmlAttribute")) {
1043                 return "Yes";
1044             }
1045         }
1046         return "No";
1047     }
1048 
1049     private JavaField findField(JavaClass javaClass, String shortName,
1050             JavaMethod setterMethod) {
1051         JavaField field = findField(javaClass, shortName);
1052         if (field != null) {
1053             return field;
1054         }
1055         if (setterMethod != null) {
1056             String paramName = setterMethod.getParameters()[0].getName();
1057             if (paramName.equalsIgnoreCase(shortName)) {
1058                 return null;
1059             }
1060             return findField(javaClass, paramName);
1061         }
1062         return null;
1063     }
1064 
1065     private JavaField findField(JavaClass javaClass, String name) {
1066         if (name == null) {
1067             return null;
1068         }
1069         for (JavaField field : javaClass.getFields()) {
1070             if (field.getName().equalsIgnoreCase(name)) {
1071                 return field;
1072             }
1073             // TODO: check for shortNames that already start with is so we don't check for isIsEnrollable
1074             if (field.getName().equals("is" + name)) {
1075                 return field;
1076             }
1077         }
1078         JavaClass superClass = javaClass.getSuperJavaClass();
1079         if (superClass == null) {
1080             return null;
1081         }
1082         return findField(superClass, name);
1083     }
1084 
1085     private JavaMethod findGetterMethod(JavaClass msClass, String shortName) {
1086         for (JavaMethod method : msClass.getMethods(true)) {
1087             if (method.getName().equalsIgnoreCase("get" + shortName)) {
1088                 return method;
1089             }
1090             if (method.getName().toLowerCase().startsWith("is")) {
1091                 if (method.getName().equalsIgnoreCase("is" + shortName)) {
1092                     return method;
1093                 }
1094                 // shortName already has "is" in it
1095                 if (method.getName().equalsIgnoreCase(shortName)) {
1096                     return method;
1097                 }
1098             }
1099             // TODO: followup on KimEntityResidencyInfo.getInState
1100             if (method.getName().equalsIgnoreCase("getInState") && shortName.equalsIgnoreCase(
1101                     "InStateFlag")) {
1102                 return method;
1103             }
1104         }
1105         return null;
1106     }
1107 
1108     private JavaMethod findSetterMethod(JavaClass msClass, String shortName) {
1109         for (JavaMethod method : msClass.getMethods(true)) {
1110             if (method.getName().equals("set" + shortName)) {
1111                 return method;
1112             }
1113             // TODO: check for shortNames that already start with is so we don't check for isIsEnrollable
1114             if (method.getName().equals("setIs" + shortName)) {
1115                 return method;
1116             }
1117             // TODO: followup on KimEntityResidencyInfo.getInState
1118             if (method.getName().equals("setInStateFlag") && shortName.equals(
1119                     "InState")) {
1120                 return method;
1121             }
1122         }
1123         return null;
1124     }
1125     private static final String[] SETTER_METHODS_TO_SKIP = {
1126         // Somebody put "convenience" methods on the validation result info
1127         "ValidationResultInfo.setWarning",
1128         "ValidationResultInfo.setError",
1129         // not on original wiki but still defined as a method but not backed by a field so not in wsdl
1130         "CredentialProgramInfo.setDiplomaTitle",
1131         // synonym for the official of setCredentialType
1132         "CredentialProgramInfo.setType",
1133         // not on original wiki but still defined as a method but not backed by a field so not in wsdl
1134         "CredentialProgramInfo.setHegisCode",
1135         "CredentialProgramInfo.setCip2000Code",
1136         "CredentialProgramInfo.setCip2010Code",
1137         "CredentialProgramInfo.setSelectiveEnrollmentCode",
1138         "CoreProgramInfo.setDiplomaTitle",
1139         // synonym for the official of setCredentialType
1140         //  "CoreProgramInfo.setType",
1141         // not on original wiki but still defined as a method but not backed by a field so not in wsdl
1142         "CoreProgramInfo.setHegisCode",
1143         "CoreProgramInfo.setCip2000Code",
1144         "CoreProgramInfo.setCip2010Code",
1145         "CoreProgramInfo.setSelectiveEnrollmentCode",
1146         "WhenConstraint.setValue"
1147     };
1148     private static final String[] GETTER_METHODS_TO_SKIP = {
1149         // Somebody put "convenience" methods on the validation result info
1150         "ValidationResultInfo.getWarning",
1151         "ValidationResultInfo.getError",
1152         // not on original wiki but still defined as a method but not backed by a field so not in wsdl
1153         "CredentialProgramInfo.getDiplomaTitle",
1154         // synonym for the official of setCredentialType
1155         "CredentialProgramInfo.getType",
1156         // not on original wiki but still defined as a method but not backed by a field so not in wsdl
1157         "CredentialProgramInfo.getHegisCode",
1158         "CredentialProgramInfo.getCip2000Code",
1159         "CredentialProgramInfo.getCip2010Code",
1160         "CredentialProgramInfo.getSelectiveEnrollmentCode",
1161         "CoreProgramInfo.getDiplomaTitle",
1162         // synonym for the official of setCredentialType
1163         //  "CoreProgramInfo.setType",
1164         // not on original wiki but still defined as a method but not backed by a field so not in wsdl
1165         "CoreProgramInfo.getHegisCode",
1166         "CoreProgramInfo.getCip2000Code",
1167         "CoreProgramInfo.getCip2010Code",
1168         "CoreProgramInfo.getSelectiveEnrollmentCode",
1169         "WhenConstraint.getValue"
1170     };
1171 
1172     private boolean isSetterMethodToProcess(JavaMethod method, String className) {
1173         if (!method.getName().startsWith("set")) {
1174             return false;
1175         }
1176         if (method.getParameters().length != 1) {
1177             return false;
1178         }
1179         if (method.isPrivate()) {
1180             return false;
1181         }
1182         if (method.isProtected()) {
1183             return false;
1184         }
1185         if (method.isStatic()) {
1186             return false;
1187         }
1188         if (method.getParentClass().getPackageName().startsWith("java")) {
1189             return false;
1190         }
1191         String fullName = className + "." + method.getName();
1192         for (String skip : SETTER_METHODS_TO_SKIP) {
1193             if (skip.equals(fullName)) {
1194                 return false;
1195             }
1196         }
1197 //  if (method.getParentClass ().isInterface ())
1198 //  {
1199 //   return false;
1200 //  }
1201         for (Annotation annotation : method.getAnnotations()) {
1202             if (annotation.getType().getJavaClass().getName().equals("XmlTransient")) {
1203                 return false;
1204             }
1205         }
1206         return true;
1207     }
1208 
1209     private boolean isGetterMethodToProcess(JavaMethod method, String className) {
1210         if (!method.getName().startsWith("get")) {
1211             if (!method.getName().startsWith("is")) {
1212                 return false;
1213             }
1214         }
1215         if (method.getParameters().length != 0) {
1216             return false;
1217         }
1218         if (method.isPrivate()) {
1219             return false;
1220         }
1221         if (method.isProtected()) {
1222             return false;
1223         }
1224         if (method.isStatic()) {
1225             return false;
1226         }
1227         if (method.getParentClass().getPackageName().startsWith("java")) {
1228             return false;
1229         }
1230         String fullName = className + "." + method.getName();
1231         for (String skip : GETTER_METHODS_TO_SKIP) {
1232             if (skip.equals(fullName)) {
1233                 return false;
1234             }
1235         }
1236 //  if (method.getParentClass ().isInterface ())
1237 //  {
1238 //   return false;
1239 //  }
1240         for (Annotation annotation : method.getAnnotations()) {
1241             if (annotation.getType().getJavaClass().getName().equals("XmlTransient")) {
1242                 return false;
1243             }
1244         }
1245         return true;
1246     }
1247 
1248     private String calcShortNameFromSetter(JavaMethod method) {
1249         return method.getName().substring(3);
1250     }
1251 
1252     private String calcShortNameFromGetter(JavaMethod method) {
1253         if (method.getName().startsWith("get")) {
1254             return method.getName().substring(3);
1255         }
1256         if (method.getName().startsWith("is")) {
1257             return method.getName().substring(2);
1258         }
1259         throw new IllegalArgumentException(method.getName()
1260                 + " does not start with is or get");
1261     }
1262 
1263     private String calcCardinality(JavaClass mainClass, JavaMethod getterMethod,
1264             JavaMethod setterMethod, JavaField beanField, String shortName) {
1265         if (isReturnACollection(mainClass, getterMethod, setterMethod, beanField, shortName)) {
1266             return "Many";
1267         }
1268         return "One";
1269     }
1270 
1271     private boolean isReturnACollection(JavaClass mainClass, JavaMethod getterMethod,
1272             JavaMethod setterMethod, JavaField beanField, String shortName) {
1273         if (getterMethod != null) {
1274             return isCollection(getterMethod.getReturnType());
1275         }
1276         if (beanField != null) {
1277             return isCollection(beanField.getType());
1278         }
1279         // TODO: check setterMethod
1280         return false;
1281     }
1282 
1283     private boolean isCollection(Type type) {
1284         JavaClass javaClass = type.getJavaClass();
1285         return this.isCollection(javaClass);
1286     }
1287 
1288     private boolean isCollection(JavaClass javaClass) {
1289         if (javaClass.getName().equals("LocalKeyList")) {
1290             return true;
1291         }
1292         if (javaClass.getName().equals("MessageGroupKeyList")) {
1293             return true;
1294         }
1295         if (javaClass.getName().equals(List.class.getSimpleName())) {
1296             return true;
1297         }
1298         if (javaClass.getName().equals(ArrayList.class.getSimpleName())) {
1299             return true;
1300         }
1301         if (javaClass.getName().equals(Collection.class.getSimpleName())) {
1302             return true;
1303         }
1304         if (javaClass.getName().equals(Set.class.getSimpleName())) {
1305             return true;
1306         }
1307         return false;
1308     }
1309 
1310     private String calcType(JavaClass mainClass, JavaMethod getterMethod,
1311             JavaMethod setterMethod, JavaField beanField, String shortName) {
1312         if (getterMethod != null) {
1313             return calcTypeOfGetterMethodReturn(getterMethod);
1314         }
1315         if (beanField != null) {
1316             Type type = beanField.getType();
1317             return calcType(type);
1318         }
1319         // TODO: calc type based on the setterMethod
1320         return null;
1321     }
1322 
1323     private String calcTypeOfGetterMethodReturn(JavaMethod getterMethod) {
1324         Type type = getterMethod.getReturnType();
1325         return calcType(type);
1326     }
1327 
1328     private String calcTypeOfSetterMethodFirstParam(JavaMethod setterMethod) {
1329         JavaParameter param = setterMethod.getParameters()[0];
1330         return calcType(param);
1331     }
1332 
1333     private String calcType(JavaParameter parameter) {
1334         return calcType(parameter.getType());
1335     }
1336 
1337     private String calcType(Type type) {
1338         if (type == null) {
1339             return "void";
1340         }
1341         if (isCollection(type.getJavaClass())) {
1342             return calcType(calcRealJavaClass(type)) + "List";
1343         }
1344         return calcType(calcRealJavaClass(type));
1345     }
1346 
1347     private String calcType(JavaClass javaClass) {
1348         if (javaClass.isEnum()) {
1349             // TODO: instead of hand mapping this take it based on the class in the @XmlEnum(String.class) tag
1350             if (javaClass.getName().equals("ErrorLevel")) {
1351                 return "Integer";
1352             }
1353             if (javaClass.getName().equals("StatementOperatorTypeKey")) {
1354                 return "String";
1355             }
1356             if (javaClass.getName().equals("WriteAccess")) {
1357                 return "String";
1358             }
1359             if (javaClass.getName().equals("Widget")) {
1360                 return "String";
1361             }
1362             if (javaClass.getName().equals("DataType")) {
1363                 return "String";
1364             }
1365             if (javaClass.getName().equals("SortDirection")) {
1366                 return "String";
1367             }
1368             if (javaClass.getName().equals("Usage")) {
1369                 return "String";
1370             }
1371             if (javaClass.getName().equals("StatementOperator")) {
1372                 return "String";
1373             }
1374         }
1375         // this is messed up instead of list of strings it is an object with a list of strings
1376         if (javaClass.getName().equals(LOCALE_KEY_LIST)) {
1377             return "StringList";
1378         }
1379         if (javaClass.getName().equals(MESSAGE_GROUP_KEY_LIST)) {
1380             return "StringList";
1381         }
1382         // TODO: figure out why rice stuff translates like this junk?
1383         if (javaClass.getName().equals("java$util$Map")) {
1384             return "Map<String, String>";
1385         }
1386         if (javaClass.getName().equals("Map")) {
1387             // TODO: make sure it is in fact a String,String map
1388             return "Map<String, String>";
1389         }
1390         return javaClass.getName();
1391     }
1392 
1393     private JavaClass calcRealJavaClassOfGetterReturn(JavaMethod getterMethod) {
1394         if (getterMethod == null) {
1395             return null;
1396         }
1397         Type type = getterMethod.getReturnType();
1398         return this.calcRealJavaClass(type);
1399     }
1400 
1401     private JavaClass calcRealJavaClassOfSetterFirstParam(JavaMethod setterMethod) {
1402         JavaParameter param = setterMethod.getParameters()[0];
1403         return this.calcRealJavaClass(param);
1404     }
1405 
1406     private JavaClass calcRealJavaClass(JavaParameter param) {
1407         Type type = param.getType();
1408         return calcRealJavaClass(type);
1409     }
1410 
1411     private JavaClass calcRealJavaClass(Type type) {
1412         if (type == null) {
1413             return null;
1414         }
1415         JavaClass javaClass = type.getJavaClass();
1416         if (javaClass.getName().equals(LOCALE_KEY_LIST)) {
1417             return STRING_JAVA_CLASS;
1418         }
1419         if (javaClass.getName().equals(MESSAGE_GROUP_KEY_LIST)) {
1420             return STRING_JAVA_CLASS;
1421         }
1422         if (!this.isCollection(javaClass)) {
1423             return javaClass;
1424         }
1425 
1426 //  for (Type t : type.getActualTypeArguments ())
1427 //  {
1428 //   System.out.println ("ServiceContractModelQDoxLoader: type arguments = "
1429 //                       + t.toString ());
1430 //  }
1431 
1432         Type t = type.getActualTypeArguments()[0];
1433         return t.getJavaClass();
1434     }
1435 
1436     private boolean isComplex(JavaClass javaClass) {
1437         if (javaClass.isEnum()) {
1438             return false;
1439         }
1440         if (javaClass.getName().equals(String.class.getSimpleName())) {
1441             return false;
1442         }
1443         if (javaClass.getName().equals(Integer.class.getSimpleName())) {
1444             return false;
1445         }
1446         if (javaClass.getName().equals(Date.class.getSimpleName())) {
1447             return false;
1448         }
1449         if (javaClass.getName().equals(Long.class.getSimpleName())) {
1450             return false;
1451         }
1452         if (javaClass.getName().equals(Boolean.class.getSimpleName())) {
1453             return false;
1454         }
1455         if (javaClass.getName().equals(Double.class.getSimpleName())) {
1456             return false;
1457         }
1458         if (javaClass.getName().equals(Float.class.getSimpleName())) {
1459             return false;
1460         }
1461         if (javaClass.getName().equals(int.class.getSimpleName())) {
1462             return false;
1463         }
1464         if (javaClass.getName().equals(long.class.getSimpleName())) {
1465             return false;
1466         }
1467         if (javaClass.getName().equals(boolean.class.getSimpleName())) {
1468             return false;
1469         }
1470         if (javaClass.getName().equals(double.class.getSimpleName())) {
1471             return false;
1472         }
1473         if (javaClass.getName().equals(float.class.getSimpleName())) {
1474             return false;
1475         }
1476         if (javaClass.getName().equals(Map.class.getSimpleName())) {
1477             return false;
1478         }
1479 
1480         if (javaClass.getName().equals(String.class.getName())) {
1481             return false;
1482         }
1483         if (javaClass.getName().equals(Integer.class.getName())) {
1484             return false;
1485         }
1486         if (javaClass.getName().equals(Date.class.getName())) {
1487             return false;
1488         }
1489         if (javaClass.getName().equals(Long.class.getName())) {
1490             return false;
1491         }
1492         if (javaClass.getName().equals(Boolean.class.getName())) {
1493             return false;
1494         }
1495         if (javaClass.getName().equals(Double.class.getName())) {
1496             return false;
1497         }
1498         if (javaClass.getName().equals(Float.class.getName())) {
1499             return false;
1500         }
1501         if (javaClass.getName().equals(int.class.getName())) {
1502             return false;
1503         }
1504         if (javaClass.getName().equals(long.class.getName())) {
1505             return false;
1506         }
1507         if (javaClass.getName().equals(boolean.class.getName())) {
1508             return false;
1509         }
1510         if (javaClass.getName().equals(double.class.getName())) {
1511             return false;
1512         }
1513         if (javaClass.getName().equals(float.class.getName())) {
1514             return false;
1515         }
1516         if (javaClass.getName().equals(Map.class.getName())) {
1517             return false;
1518         }
1519         if (javaClass.getName().equals(LOCALE_KEY_LIST)) {
1520             return false;
1521         }
1522         if (javaClass.getName().equals(MESSAGE_GROUP_KEY_LIST)) {
1523             return false;
1524         }
1525         if (javaClass.getName().equals("java$util$Map")) {
1526             return false;
1527         }
1528         return true;
1529     }
1530 }