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