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 }