001 /*
002 * Copyright 2010 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.impl;
017
018 import com.thoughtworks.qdox.JavaDocBuilder;
019 import com.thoughtworks.qdox.model.Annotation;
020 import com.thoughtworks.qdox.model.DefaultDocletTagFactory;
021 import com.thoughtworks.qdox.model.DocletTag;
022 import com.thoughtworks.qdox.model.JavaClass;
023 import com.thoughtworks.qdox.model.JavaField;
024 import com.thoughtworks.qdox.model.JavaMethod;
025 import com.thoughtworks.qdox.model.JavaParameter;
026 import com.thoughtworks.qdox.model.Type;
027 import com.thoughtworks.qdox.model.annotation.AnnotationValue;
028 import java.io.File;
029 import java.util.ArrayList;
030 import java.util.Arrays;
031 import java.util.Collection;
032 import java.util.Collections;
033 import java.util.Date;
034 import java.util.LinkedHashMap;
035 import java.util.LinkedHashSet;
036 import java.util.List;
037 import java.util.Map;
038 import java.util.Set;
039
040 import org.kuali.student.contract.model.MessageStructure;
041 import org.kuali.student.contract.model.Service;
042 import org.kuali.student.contract.model.ServiceContractModel;
043 import org.kuali.student.contract.model.ServiceMethod;
044 import org.kuali.student.contract.model.ServiceMethodError;
045 import org.kuali.student.contract.model.ServiceMethodParameter;
046 import org.kuali.student.contract.model.ServiceMethodReturnValue;
047 import org.kuali.student.contract.model.XmlType;
048
049 /**
050 *
051 * @author nwright
052 */
053 public class ServiceContractModelQDoxLoader implements
054 ServiceContractModel {
055
056 private static final String LOCALE_KEY_LIST = "LocaleKeyList";
057 private static final String MESSAGE_GROUP_KEY_LIST = "MessageGroupKeyList";
058 private static final JavaClass STRING_JAVA_CLASS = new JavaClass(
059 "java.lang.String");
060 private List<String> sourceDirectories = null;
061 private List<Service> services = null;
062 private List<ServiceMethod> serviceMethods = null;
063 private Map<String, XmlType> xmlTypeMap = null;
064 private List<MessageStructure> messageStructures;
065 private boolean validateKualiStudent = true;
066
067 public ServiceContractModelQDoxLoader(List<String> sourceDirectories) {
068 this.sourceDirectories = sourceDirectories;
069 }
070
071 public ServiceContractModelQDoxLoader(List<String> sourceDirectories, boolean validateKualiStudent) {
072 this.sourceDirectories = sourceDirectories;
073 this.setValidateKualiStudent(validateKualiStudent);
074 }
075
076 public boolean isValidateKualiStudent() {
077 return validateKualiStudent;
078 }
079
080 public void setValidateKualiStudent(boolean validateKualiStudent) {
081 this.validateKualiStudent = validateKualiStudent;
082 }
083
084 @Override
085 public List<ServiceMethod> getServiceMethods() {
086 if (this.serviceMethods == null) {
087 this.parse();
088 }
089 return this.serviceMethods;
090 }
091
092 @Override
093 public List<String> getSourceNames() {
094 List<String> list = new ArrayList(this.sourceDirectories.size());
095 for (String javaFile : this.sourceDirectories) {
096 list.add(javaFile);
097 }
098 return list;
099 }
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 }