001 /** 002 * Copyright 2004-2014 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.opensource.org/licenses/ecl2.php 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.*; 020 import com.thoughtworks.qdox.model.Type; 021 import com.thoughtworks.qdox.model.annotation.AnnotationValue; 022 import org.kuali.student.contract.model.*; 023 import org.kuali.student.contract.model.util.JavaClassAnnotationUtils; 024 import org.slf4j.Logger; 025 import org.slf4j.LoggerFactory; 026 027 import javax.xml.bind.annotation.XmlEnum; 028 import java.io.File; 029 import java.math.BigDecimal; 030 import java.util.*; 031 032 /** 033 * 034 * @author nwright 035 */ 036 public class ServiceContractModelQDoxLoader implements 037 ServiceContractModel { 038 039 private static final Logger log = LoggerFactory.getLogger(ServiceContractModelQDoxLoader.class); 040 041 private static final String LOCALE_KEY_LIST = "LocaleKeyList"; 042 private static final String MESSAGE_GROUP_KEY_LIST = "MessageGroupKeyList"; 043 private static final JavaClass STRING_JAVA_CLASS = new JavaClass( 044 "java.lang.String"); 045 private List<String> sourceDirectories = null; 046 private List<Service> services = null; 047 private List<ServiceMethod> serviceMethods = null; 048 private Map<String, XmlType> xmlTypeMap = null; 049 private List<MessageStructure> messageStructures; 050 private boolean validateKualiStudent; 051 052 public ServiceContractModelQDoxLoader(List<String> sourceDirectories) { 053 this (sourceDirectories, true); 054 } 055 056 public ServiceContractModelQDoxLoader(List<String> sourceDirectories, boolean validateKualiStudent) { 057 this.sourceDirectories = sourceDirectories; 058 this.setValidateKualiStudent(validateKualiStudent); 059 } 060 061 public boolean isValidateKualiStudent() { 062 return validateKualiStudent; 063 } 064 065 public void setValidateKualiStudent(boolean validateKualiStudent) { 066 this.validateKualiStudent = validateKualiStudent; 067 } 068 069 @Override 070 public List<ServiceMethod> getServiceMethods() { 071 if (this.serviceMethods == null) { 072 this.parse(); 073 } 074 return this.serviceMethods; 075 } 076 077 @Override 078 public List<String> getSourceNames() { 079 List<String> list = new ArrayList<String>(this.sourceDirectories.size()); 080 for (String javaFile : this.sourceDirectories) { 081 list.add(javaFile); 082 } 083 return list; 084 } 085 086 @Override 087 public List<Service> getServices() { 088 if (services == null) { 089 this.parse(); 090 } 091 return services; 092 } 093 094 @Override 095 public List<XmlType> getXmlTypes() { 096 if (xmlTypeMap == null) { 097 this.parse(); 098 } 099 return new ArrayList<XmlType>(xmlTypeMap.values()); 100 } 101 102 @Override 103 public List<MessageStructure> getMessageStructures() { 104 if (messageStructures == null) { 105 this.parse(); 106 } 107 return this.messageStructures; 108 } 109 110 private void checkIfExists(String sourceDirectory) { 111 File file = new File(sourceDirectory); 112 if (!file.isDirectory()) { 113 throw new IllegalArgumentException(sourceDirectory + " is not a directory on disk"); 114 } 115 } 116 117 @SuppressWarnings("unchecked") 118 private void parse() { 119 // System.out.println ("ServiceContractModelQDoxLoader: Starting parse"); 120 services = new ArrayList<Service>(); 121 serviceMethods = new ArrayList<ServiceMethod>(); 122 xmlTypeMap = new LinkedHashMap<String, XmlType>(); 123 messageStructures = new ArrayList<MessageStructure>(); 124 125 DefaultDocletTagFactory dtf = new DefaultDocletTagFactory(); 126 127 JavaDocBuilder builder = new JavaDocBuilder(dtf); 128 129 for (String sourceDirectory : sourceDirectories) { 130 checkIfExists(sourceDirectory); 131 builder.addSourceTree(new File(sourceDirectory)); 132 } 133 Set<JavaClass> mergedClasses = new LinkedHashSet<JavaClass>(); 134 135 for (JavaClass javaClass : builder.getClasses()) { 136 137 if (!javaClass.getPackageName().contains("r1")) 138 mergedClasses.add(javaClass); 139 else 140 log.warn("excluding r1 class: " + javaClass.getFullyQualifiedName()); 141 142 } 143 144 List<JavaClass>sortedClasses = new ArrayList<JavaClass>(mergedClasses); 145 146 Collections.sort(sortedClasses); 147 148 for (JavaClass javaClass : sortedClasses) { 149 if (!this.isServiceToProcess(javaClass)) { 150 continue; 151 } 152 // System.out.println ("processing service=" + javaClass.getName ()); 153 Service service = new Service(); 154 services.add(service); 155 service.setKey(calcServiceKey (javaClass)); 156 service.setName(javaClass.getName()); 157 service.setComments(this.calcComment(javaClass)); 158 service.setUrl(this.calcServiceUrl(javaClass)); 159 service.setVersion(this.calcVersion(javaClass)); 160 service.setStatus("???"); 161 service.setIncludedServices(calcIncludedServices(javaClass)); 162 service.setImplProject(javaClass.getPackageName()); 163 164 // for (DocletTag tag : javaClass.getTags ()) 165 // { 166 // System.out.println ("ServiceContractModelQDoxLoader: Class: " 167 // + javaClass.getName () + " has tag=" + dump ( 168 // tag)); 169 // } 170 171 JavaMethod[] methods = getServiceMethods (javaClass); 172 for (JavaMethod javaMethod : methods) { 173 174 ServiceMethod serviceMethod = new ServiceMethod(); 175 serviceMethods.add(serviceMethod); 176 serviceMethod.setService(service.getKey()); 177 serviceMethod.setName(javaMethod.getName()); 178 serviceMethod.setDescription(calcMissing(javaMethod.getComment())); 179 serviceMethod.setParameters(new ArrayList<ServiceMethodParameter>()); 180 serviceMethod.setImplNotes(calcImplementationNotes(javaMethod)); 181 serviceMethod.setDeprecated(isDeprecated(javaMethod)); 182 // for (DocletTag tag : javaMethod.getTags ()) 183 // { 184 // System.out.println ("ServiceContractModelQDoxLoader: Method: " 185 // + service.getName () + "." 186 // + javaMethod.getName () 187 // + " has tag=" + dump (tag)); 188 // } 189 // parameters 190 for (JavaParameter parameter : javaMethod.getParameters()) { 191 ServiceMethodParameter param = new ServiceMethodParameter(); 192 serviceMethod.getParameters().add(param); 193 param.setName(parameter.getName()); 194 param.setType(calcType(parameter.getType())); 195 param.setDescription(calcMissing( 196 calcParameterDescription(javaMethod, 197 param.getName()))); 198 try { 199 addXmlTypeAndMessageStructure(calcRealJavaClass(parameter.getType()), 200 serviceMethod.getService()); 201 } catch (Exception e) { 202 String message= "failed to parameter message structure: " + serviceMethod.getService() + " : " + parameter.getType(); 203 204 log.error (message + " : " + e.getMessage()); 205 log.debug(message, e); 206 } 207 } 208 // errors 209 serviceMethod.setErrors(new ArrayList<ServiceMethodError>()); 210 for (Type exception : javaMethod.getExceptions()) { 211 ServiceMethodError error = new ServiceMethodError(); 212 error.setType(this.calcType(exception.getJavaClass())); 213 error.setDescription(calcMissing( 214 calcExceptionDescription(javaMethod, 215 error.getType()))); 216 error.setPackageName(exception.getJavaClass().getPackageName()); 217 error.setClassName(exception.getJavaClass().getName()); 218 serviceMethod.getErrors().add(error); 219 } 220 // return values 221 ServiceMethodReturnValue rv = new ServiceMethodReturnValue(); 222 serviceMethod.setReturnValue(rv); 223 Type returnType = null; 224 try { 225 returnType = javaMethod.getReturnType(); 226 } catch (NullPointerException ex) { 227 log.error("Nullpointer getting return type: " + javaMethod.getCallSignature()); 228 returnType = null; 229 } 230 231 rv.setType(calcType(returnType)); 232 rv.setDescription(calcMissing(this.calcReturnDescription(javaMethod))); 233 if (returnType != null) { 234 try { 235 236 237 addXmlTypeAndMessageStructure(calcRealJavaClass(returnType), 238 serviceMethod.getService()); 239 } catch (Exception e) { 240 String message = "failed to parse return type message structure: " + serviceMethod.getService() + " : " + returnType; 241 242 log.error (message + " : " + e.getMessage()); 243 log.debug(message, e); 244 } 245 } 246 } 247 } 248 } 249 250 251 private String calcServiceKey(JavaClass javaClass) { 252 String key = javaClass.getName(); 253 if (key.endsWith ("Service")) { 254 key = key.substring(0, key.length() - "Service".length()); 255 } 256 if (javaClass.getPackageName().startsWith("org.kuali.rice.")) { 257 log.warn("WARNING " + " changing servkey for the RICE services to include prefix " 258 + " to disambiguate with Kuali Student StateService See Jira KSENROLL-2892"); 259 key = "RICE." + key; 260 } 261 return key; 262 } 263 264 private JavaMethod[] getServiceMethods(JavaClass javaClass) { 265 266 Set<JavaMethod>methods = new LinkedHashSet<JavaMethod>(); 267 268 /* 269 * As inheritence is useful from a technical level but not as much from a business level 270 * This lets the union of the methods from all of the interfaces be listed in the contract. 271 */ 272 JavaClass[] interfaces = javaClass.getImplementedInterfaces(); 273 274 for (JavaClass intfc : interfaces) { 275 276 if (!isAService(intfc)) { 277 // only add the methods if this is not a service 278 // e.g. extends ServiceBusinessLogic 279 for (JavaMethod javaMethod : intfc.getMethods()) { 280 281 methods.add(javaMethod); 282 } 283 } 284 285 } 286 287 // add the main service methods last incase we override any from the parent interfaces. 288 // note the heirarchy is only guaranteed relative to the target service class (if there are two levels or more of 289 // heirarchy there is no guarantee the method ordering will be correct). 290 for (JavaMethod javaMethod : javaClass.getMethods()) { 291 292 methods.add(javaMethod); 293 } 294 295 return methods.toArray(new JavaMethod[] {}); 296 } 297 298 private boolean isServiceToProcess(JavaClass javaClass) { 299 // System.out.println ("looking if javaClass is a service to process=" + javaClass.getName () + "=" + javaClass.getPackageName ()); 300 301 if (!javaClass.getName().endsWith("Service")) { 302 return false; 303 } 304 if (javaClass.getPackageName().contains(".old.")) { 305 306 return false; 307 } 308 if (javaClass.getPackageName().endsWith(".old")) { 309 return false; 310 } 311 for (Annotation annotation : javaClass.getAnnotations()) { 312 // System.out.println ("looking for webservice tag=" + annotation.getType ().getJavaClass ().getName ()); 313 if (annotation.getType().getJavaClass().getName().equals("WebService")) { 314 // System.out.println ("Processing web service=" + javaClass.getPackageName () 315 // + "." + javaClass.getName ()); 316 return true; 317 } 318 } 319 // This includes RICE's business object services even though they are not web services 320 // because often they are the only real service they have exposed and it helps to document 321 // them to see what the data really is like 322 if (javaClass.getName().endsWith("BoService")) { 323 return true; 324 } 325 // This includes KSA's internal services even though they are not web services 326 if (javaClass.getPackageName().startsWith("com.sigmasys.kuali.ksa.service")) { 327 return true; 328 } 329 if (javaClass.getPackageName().startsWith("org.kuali.mobility")) { 330 return true; 331 } 332 // System.out.println ("skipping service because it is not a web service=" 333 // + javaClass.getPackageName () + "." + javaClass.getName ()); 334 return false; 335 } 336 337 private List<String> calcIncludedServices(JavaClass javaClass) { 338 List<String> includedServices = new ArrayList<String>(); 339 for (JavaClass interfaceClass : javaClass.getImplementedInterfaces()) { 340 if (isAService(interfaceClass)) { 341 // System.out.println("ServiceContractModelQDoxLoader:" + javaClass.getName() 342 // + " implements " + interfaceClass.getName()); 343 includedServices.add(interfaceClass.getName()); 344 } 345 } 346 return includedServices; 347 } 348 349 private boolean isAService(JavaClass interfaceClass) { 350 if (interfaceClass.getName().endsWith("Service")) { 351 return true; 352 } 353 return false; 354 } 355 356 private String calcParameterDescription(JavaMethod method, 357 String parameterName) { 358 for (DocletTag tag : method.getTags()) { 359 if (tag.getName().equals("param")) { 360 if (tag.getValue().startsWith(parameterName + " ")) { 361 return tag.getValue().substring(parameterName.length() + 1); 362 } 363 } 364 } 365 return null; 366 } 367 368 private String calcExceptionDescription(JavaMethod serviceMethod, 369 String exceptionType) { 370 for (DocletTag tag : serviceMethod.getTags()) { 371 if (tag.getName().equals("throws")) { 372 if (tag.getValue().startsWith(exceptionType + " ")) { 373 return tag.getValue().substring(exceptionType.length() + 1); 374 } 375 } 376 } 377 return null; 378 } 379 380 private String calcReturnDescription(JavaMethod serviceMethod) { 381 for (DocletTag tag : serviceMethod.getTags()) { 382 if (tag.getName().equals("return")) { 383 return tag.getValue(); 384 } 385 } 386 return null; 387 } 388 389 private String calcServiceUrl(JavaClass serviceClass) { 390 for (DocletTag tag : serviceClass.getTags()) { 391 if (tag.getName().equals("See")) { 392 return tag.getValue(); 393 } 394 } 395 return null; 396 } 397 398 private void addXmlTypeAndMessageStructure(JavaClass messageStructureJavaClass, 399 String serviceKey) { 400 String name = calcType(messageStructureJavaClass); 401 if (name.endsWith("CallbackService")) { 402 return; 403 } 404 XmlType xmlType = xmlTypeMap.get(name); 405 if (xmlType == null) { 406 xmlType = new XmlType(); 407 xmlTypeMap.put(name, xmlType); 408 xmlType.setName(name); 409 xmlType.setDesc(this.calcMessageStructureDesc(messageStructureJavaClass)); 410 xmlType.setDeprecated(isDeprecated (messageStructureJavaClass)); 411 xmlType.setService(serviceKey); 412 xmlType.setVersion("IGNORE -- SAME AS SERVICE"); 413 xmlType.setPrimitive(calcPrimitive(messageStructureJavaClass)); 414 xmlType.setJavaPackage(calcJavaPackage(messageStructureJavaClass)); 415 if (xmlType.getPrimitive().equals(XmlType.COMPLEX)) { 416 addMessageStructure(messageStructureJavaClass, serviceKey); 417 } 418 419 } else { 420 addServiceToList(xmlType, serviceKey); 421 } 422 } 423 424 private boolean isDeprecated(JavaClass javaClass) { 425 for (Annotation annotation : javaClass.getAnnotations()) { 426 if (annotation.getType().getJavaClass().getName().equals( 427 "Deprecated")) { 428 return true; 429 } 430 } 431 return false; 432 } 433 434 private String calcJavaPackage(JavaClass javaClass) { 435 String packageName = javaClass.getPackageName(); 436 return packageName; 437 } 438 439 private String calcMessageStructureDesc(JavaClass javaClass) { 440 { 441 String desc = javaClass.getComment(); 442 if (desc != null) { 443 if (!desc.isEmpty()) { 444 return desc; 445 } 446 } 447 JavaClass infcClass = this.getMatchingInfc(javaClass); 448 if (infcClass == null) { 449 return null; 450 } 451 return infcClass.getComment(); 452 } 453 } 454 455 private JavaClass getMatchingInfc(JavaClass javaClass) { 456 // ks uses this pattern 457 String nameInfc = javaClass.getName(); 458 if (nameInfc.endsWith("Info")) { 459 nameInfc = nameInfc.substring(0, nameInfc.length() - "Info".length()) 460 + "Infc"; 461 } 462 String nameWithOutInfo = javaClass.getName(); 463 // rice uses this pattern 464 if (nameWithOutInfo.endsWith("Info")) { 465 nameWithOutInfo = nameWithOutInfo.substring(0, nameWithOutInfo.length() 466 - "Info".length()); 467 } 468 for (JavaClass infc : javaClass.getImplementedInterfaces()) { 469 if (infc.getName().equals(nameInfc)) { 470 // System.out.println("found matching interface " + infc.getName()); 471 return infc; 472 } 473 if (infc.getName().equals(nameWithOutInfo)) { 474 return infc; 475 } 476 } 477 return null; 478 } 479 480 private String calcPrimitive(JavaClass javaClass) { 481 if (this.isComplex(javaClass)) { 482 return XmlType.COMPLEX; 483 } 484 return "Primitive"; 485 } 486 487 private String initLower(String str) { 488 if (str == null) { 489 return null; 490 } 491 if (str.length() == 0) { 492 return str; 493 } 494 if (str.length() == 1) { 495 return str.toLowerCase(); 496 } 497 return str.substring(0, 1).toLowerCase() + str.substring(1); 498 } 499 500 private String initUpper(String str) { 501 if (str == null) { 502 return null; 503 } 504 if (str.length() == 0) { 505 return str; 506 } 507 if (str.length() == 1) { 508 return str.toUpperCase(); 509 } 510 return str.substring(0, 1).toUpperCase() + str.substring(1); 511 } 512 513 private Set<String> getShortNames(JavaClass messageStructureJavaClass) { 514 Set<String> fields = getFieldsUsingPropOrder(messageStructureJavaClass); 515 if (fields != null) { 516 return fields; 517 } 518 fields = new LinkedHashSet<String>(); 519 for (JavaMethod method : messageStructureJavaClass.getMethods(true)) { 520 if (isSetterMethodToProcess(method, messageStructureJavaClass.getName())) { 521 String shortName = this.calcShortNameFromSetter(method); 522 fields.add(shortName); 523 continue; 524 } 525 if (isGetterMethodToProcess(method, messageStructureJavaClass.getName())) { 526 String shortName = this.calcShortNameFromGetter(method); 527 fields.add(shortName); 528 continue; 529 } 530 } 531 return fields; 532 } 533 534 private Set<String> getFieldsUsingPropOrder( 535 JavaClass messageStructureJavaClass) { 536 for (Annotation annotation : messageStructureJavaClass.getAnnotations()) { 537 if (annotation.getType().getJavaClass().getName().equals("XmlType")) { 538 AnnotationValue propOrderParam = annotation.getProperty("propOrder"); 539 if (propOrderParam == null) { 540 continue; 541 } 542 Object propOrderValue = propOrderParam.getParameterValue(); 543 if (!(propOrderValue instanceof List)) { 544 continue; 545 } 546 Set<String> fields = new LinkedHashSet<String>(); 547 for (Object value : (List<?>) propOrderValue) { 548 if (value instanceof String) { 549 String shortName = (String) value; 550 shortName = this.stripQuotes(shortName); 551 if (shortName.contains(".Elements.")) { 552 String newShortName = getShortNameFromElements(shortName, messageStructureJavaClass); 553 if (newShortName == null) { 554 continue; 555 } 556 shortName = newShortName; 557 } else if (shortName.startsWith("CoreConstants.CommonElements.")) { 558 String newShortName = getCoreConstants(shortName); 559 if (newShortName == null) { 560 continue; 561 } 562 shortName = newShortName; 563 } 564 if (shortName.equals("_futureElements")) { 565 continue; 566 } 567 shortName = this.initUpper(shortName); 568 fields.add(shortName); 569 } 570 } 571 return fields; 572 } 573 } 574 return null; 575 } 576 577 private String getShortNameFromElements(String shortName, JavaClass messageStructureJavaClass) { 578 JavaClass elementsJavaClass = messageStructureJavaClass.getNestedClassByName("Elements"); 579 if (elementsJavaClass == null) { 580 return null; 581 } 582 String fieldName = shortName.substring(shortName.indexOf(".Elements.") + ".Elements.".length()); 583 JavaField field = elementsJavaClass.getFieldByName(fieldName); 584 String initExpr = field.getInitializationExpression(); 585 return stripQuotes(initExpr); 586 } 587 588 private String getCoreConstants(String shortName) { 589 if (shortName.endsWith("VERSION_NUMBER")) { 590 return "versionNumber"; 591 } 592 if (shortName.endsWith("OBJECT_ID")) { 593 return "objectId"; 594 } 595 if (shortName.endsWith("ACTIVE")) { 596 return "active"; 597 } 598 if (shortName.endsWith("ACTIVE_FROM_DATE")) { 599 return "activeFromDate"; 600 } 601 if (shortName.endsWith("ACTIVE_TO_DATE")) { 602 return "activeToDate"; 603 } 604 if (shortName.endsWith("ATTRIBUTES")) { 605 return "attributes"; 606 } 607 if (shortName.endsWith("FUTURE_ELEMENTS")) { 608 return "_futureElements"; 609 } 610 throw new RuntimeException("Unknown shortName " + shortName); 611 } 612 613 private void addMessageStructure(JavaClass messageStructureJavaClass, 614 String serviceKey) { 615 Set<JavaClass> subObjectsToAdd = new LinkedHashSet<JavaClass>(); 616 for (String shortName : this.getShortNames(messageStructureJavaClass)) { 617 JavaMethod setterMethod = findSetterMethod(messageStructureJavaClass, 618 shortName); 619 JavaMethod getterMethod = findGetterMethod(messageStructureJavaClass, 620 shortName); 621 if (getterMethod == null) { 622 if (this.validateKualiStudent) { 623 throw new IllegalArgumentException("shortName has no corresponding getter method: " 624 + messageStructureJavaClass.getFullyQualifiedName() 625 + "." + shortName); 626 } 627 } 628 JavaField beanField = this.findField(messageStructureJavaClass, 629 shortName, setterMethod); 630 if (beanField == null) { 631 String accessorType = getAccessorType(getterMethod); 632 if ("XmlAccessType.FIELD".equals(accessorType)) { 633 throw new IllegalArgumentException("Setter method has no corresponding bean field: " 634 + messageStructureJavaClass.getName() 635 + "." + getterMethod.getName()); 636 } 637 } 638 // overide the shortName if the bean field has an XmlAttribute name=xxx 639 // this catches the key=id switch 640 if (beanField != null) { 641 for (Annotation annotation : beanField.getAnnotations()) { 642 if (annotation.getType().getJavaClass().getName().equals("XmlAttribute")) { 643 Object nameValue = annotation.getNamedParameter("name"); 644 if (nameValue != null) { 645 shortName = stripQuotes(nameValue.toString()); 646 } 647 } 648 } 649 } 650 shortName = initLower(shortName); 651 MessageStructure ms = new MessageStructure(); 652 messageStructures.add(ms); 653 ms.setXmlObject(messageStructureJavaClass.getName()); 654 ms.setShortName(shortName); 655 ms.setId(ms.getXmlObject() + "." + ms.getShortName()); 656 ms.setName(calcMissing(calcName(messageStructureJavaClass, getterMethod, setterMethod, 657 beanField, shortName))); 658 ms.setType(calcType(messageStructureJavaClass, getterMethod, setterMethod, beanField, shortName)); 659 if (ms.getType().equals("Object")) { 660 log.warn(ms.getId() 661 + " has Object as it's type ==> Changing to String"); 662 ms.setType("String"); 663 } else if (ms.getType().equals("ObjectList")) { 664 log.warn(ms.getId() 665 + " has a list of Objects as it's type ==> Changing to List of String"); 666 ms.setType("StringList"); 667 } 668 ms.setXmlAttribute(this.calcXmlAttribute(beanField)); 669 ms.setRequired(calcRequired(getterMethod, setterMethod, beanField)); 670 ms.setReadOnly(calcReadOnly(getterMethod, setterMethod, beanField)); 671 ms.setCardinality(this.calcCardinality(messageStructureJavaClass, getterMethod, setterMethod, beanField, shortName)); 672 ms.setDescription(calcMissing(calcDescription(messageStructureJavaClass, getterMethod, setterMethod, 673 beanField, shortName))); 674 ms.setImplNotes(calcImplementationNotes(getterMethod, setterMethod, beanField)); 675 ms.setDeprecated(isDeprecated(getterMethod)); 676 ms.setStatus("???"); 677 ms.setLookup(calcLookup (messageStructureJavaClass, getterMethod, setterMethod, 678 beanField, serviceKey, ms.getXmlObject(), shortName, ms.getType())); 679 ms.setPrimaryKey(calcPrimaryKey (messageStructureJavaClass, getterMethod, setterMethod, 680 beanField, serviceKey, ms.getXmlObject(), shortName, ms.getType())); 681 ms.setOverriden(this.calcOverridden(messageStructureJavaClass, getterMethod)); 682 JavaClass subObjToAdd = this.calcRealJavaClassOfGetterReturn(getterMethod); 683 if (subObjToAdd != null) { 684 // if (!subObjToAdd.isEnum()) { 685 if (!subObjToAdd.getName().equals("Object")) { 686 if (!subObjToAdd.getName().equals("LocaleKeyList")) { 687 if (!subObjToAdd.getName().equals("MessageGroupKeyList")) { 688 subObjectsToAdd.add(subObjToAdd); 689 } 690 } 691 } 692 // } 693 } 694 } 695 // now add all it's complex sub-objects if they haven't already been added 696 for (JavaClass subObjectToAdd : subObjectsToAdd) { 697 XmlType xmlType = xmlTypeMap.get(calcType(subObjectToAdd)); 698 if (xmlType == null) { 699 try { 700 addXmlTypeAndMessageStructure(subObjectToAdd, serviceKey); 701 } catch (Exception e) { 702 String message = "failed to parse subobject structure: " + subObjectToAdd + " : " + serviceKey; 703 // log into message 704 log.error (message + " : " + e.getMessage()); 705 // log into debug log 706 log.debug(message, e); 707 } 708 } else { 709 addServiceToList(xmlType, serviceKey); 710 } 711 } 712 return; 713 } 714 715 private String stripList (String type) { 716 if (type == null) { 717 return null; 718 } 719 if (type.endsWith("List")) { 720 return type.substring(0, type.length() - "List".length()); 721 } 722 return type; 723 } 724 725 726 private boolean calcPrimaryKey (JavaClass mainClass, JavaMethod getterMethod, 727 JavaMethod setterMethod, JavaField beanField, String serviceKey, String xmlObject, String shortName, String type) { 728 if (!type.equalsIgnoreCase ("String")) { 729 return false; 730 } 731 if (shortName.equalsIgnoreCase ("Id")) { 732 return true; 733 } 734 if (shortName.equalsIgnoreCase ("Key")) { 735 return true; 736 } 737 // Special fix up for principal 738 // log.warn(serviceKey + ":" + xmlObject + "." + shortName); 739 if (xmlObject.equalsIgnoreCase("Principal")) { 740 if (shortName.equalsIgnoreCase("principalId")) { 741 return true; 742 } 743 } 744 return false; 745 } 746 747 748 private Lookup calcLookup (JavaClass mainClass, JavaMethod getterMethod, 749 JavaMethod setterMethod, JavaField beanField, String serviceKey, String xmlObject, String shortName, String type) { 750 type = this.stripList(type); 751 // all keys and Ids are represented as strings 752 if (!type.equalsIgnoreCase ("String")) { 753 return null; 754 } 755 Lookup lookup = LOOKUP_MAPPINGS.get(shortName); 756 if (lookup == null) { 757 if (this.endsWithIdOrKey(shortName)) { 758 log.warn (serviceKey + ":" + xmlObject + "." + shortName + " ends with id or key but has no lookup defined"); 759 } 760 } 761 return lookup; 762 } 763 764 private boolean endsWithIdOrKey (String shortName) { 765 if (shortName.equals ("Id")) { 766 return false; 767 } 768 if (shortName.equals ("Key")) { 769 return false; 770 } 771 if (shortName.endsWith ("Id")) { 772 return true; 773 } 774 if (shortName.endsWith ("Ids")) { 775 return true; 776 } 777 if (shortName.endsWith ("Key")) { 778 return true; 779 } 780 if (shortName.endsWith ("Keys")) { 781 return true; 782 } 783 return false; 784 } 785 786 private static Map<String, Lookup> LOOKUP_MAPPINGS; 787 788 { 789 // global ones where the name matches the object 790 LOOKUP_MAPPINGS = new LinkedHashMap<String, Lookup> (); 791 LOOKUP_MAPPINGS.put("typeKey", new Lookup ("Type", "TypeInfo")); 792 LOOKUP_MAPPINGS.put("stateKey", new Lookup ("State", "StateInfo")); 793 LOOKUP_MAPPINGS.put("lifecycleKey", new Lookup ("State", "LifecycleInfo")); 794 LOOKUP_MAPPINGS.put("orgId", new Lookup ("Organization", "OrgInfo")); 795 LOOKUP_MAPPINGS.put("orgIds", new Lookup ("Organization", "OrgInfo")); 796 LOOKUP_MAPPINGS.put("organizationId", new Lookup ("Organization", "OrgInfo")); 797 LOOKUP_MAPPINGS.put("organizationIds", new Lookup ("Organization", "OrgInfo")); 798 LOOKUP_MAPPINGS.put("atpId", new Lookup ("Atp", "AtpInfo")); 799 LOOKUP_MAPPINGS.put("atpIds", new Lookup ("Atp", "AtpInfo")); 800 LOOKUP_MAPPINGS.put("termId", new Lookup ("AcademicCalendar", "TermInfo")); 801 LOOKUP_MAPPINGS.put("termIds", new Lookup ("AcademicCalendar", "TermInfo")); 802 LOOKUP_MAPPINGS.put("luiId", new Lookup ("Lui", "LuiInfo")); 803 LOOKUP_MAPPINGS.put("luiIds", new Lookup ("Lui", "LuiInfo")); 804 LOOKUP_MAPPINGS.put("cluId", new Lookup ("Clu", "CluInfo")); 805 LOOKUP_MAPPINGS.put("cluIds", new Lookup ("Clu", "CluInfo")); 806 LOOKUP_MAPPINGS.put("credentialProgramId", new Lookup ("Program", "CredentialProgramInfo")); 807 LOOKUP_MAPPINGS.put("credentialProgramIds", new Lookup ("Program", "CredentialProgramInfo")); 808 LOOKUP_MAPPINGS.put("credentialProgramId", new Lookup ("Program", "CredentialProgramInfo")); 809 LOOKUP_MAPPINGS.put("credentialProgramIds", new Lookup ("Program", "CredentialProgramInfo")); 810 LOOKUP_MAPPINGS.put("coreProgramId", new Lookup ("Program", "CoreProgramInfo")); 811 LOOKUP_MAPPINGS.put("coreProgramIds", new Lookup ("Program", "CoreProgramInfo")); 812 LOOKUP_MAPPINGS.put("resultScaleKey", new Lookup ("LRC", "ResultScaleInfo")); 813 LOOKUP_MAPPINGS.put("resultScaleKeys", new Lookup ("LRC", "ResultScaleInfo")); 814 LOOKUP_MAPPINGS.put("resultValuesGroupKey", new Lookup ("LRC", "ResultValuesGroupInfo")); 815 LOOKUP_MAPPINGS.put("resultValuesGroupKeys", new Lookup ("LRC", "ResultValuesGroupInfo")); 816 LOOKUP_MAPPINGS.put("resultValueKey", new Lookup ("LRC", "ResultValueInfo")); 817 LOOKUP_MAPPINGS.put("resultValueKeys", new Lookup ("LRC", "ResultValueInfo")); 818 LOOKUP_MAPPINGS.put("scheduleId", new Lookup ("Schedule", "ScheduleInfo")); 819 LOOKUP_MAPPINGS.put("scheduleIds", new Lookup ("Schedule", "ScheduleInfo")); 820 LOOKUP_MAPPINGS.put("courseId", new Lookup ("Course", "CourseInfo")); 821 LOOKUP_MAPPINGS.put("courseIds", new Lookup ("Course", "CourseInfo")); 822 LOOKUP_MAPPINGS.put("formatId", new Lookup ("Course", "FormatInfo")); 823 LOOKUP_MAPPINGS.put("formatIds", new Lookup ("Course", "FormatInfo")); 824 LOOKUP_MAPPINGS.put("activityId", new Lookup ("Course", "ActivityInfo")); 825 LOOKUP_MAPPINGS.put("activityIds", new Lookup ("Course", "ActivityInfo")); 826 LOOKUP_MAPPINGS.put("courseOfferingId", new Lookup ("CourseOffering", "CourseOfferingInfo")); 827 LOOKUP_MAPPINGS.put("courseOfferingIds", new Lookup ("CourseOffering", "CourseOfferingInfo")); 828 LOOKUP_MAPPINGS.put("formatOfferingId", new Lookup ("CourseOffering", "FormatOfferingInfo")); 829 LOOKUP_MAPPINGS.put("formatOfferingIds", new Lookup ("CourseOffering", "FormatOfferingInfo")); 830 LOOKUP_MAPPINGS.put("activityOfferingId", new Lookup ("CourseOffering", "ActivityOfferingInfo")); 831 LOOKUP_MAPPINGS.put("activityOfferingIds", new Lookup ("CourseOffering", "ActivityOfferingInfo")); 832 LOOKUP_MAPPINGS.put("socRolloverResultId", new Lookup ("CourseOfferingSet", "SorRolloverResultInfo")); 833 LOOKUP_MAPPINGS.put("socRolloverResultIds", new Lookup ("CourseOfferingSet", "SorRolloverResultInfo")); 834 LOOKUP_MAPPINGS.put("socRolloverResultItemId", new Lookup ("CourseOfferingSet", "SorRolloverResultItemInfo")); 835 LOOKUP_MAPPINGS.put("socRolloverResultItemIds", new Lookup ("CourseOfferingSet", "SorRolloverResultItemInfo")); 836 LOOKUP_MAPPINGS.put("buildingId", new Lookup ("Room", "BuildingInfo")); 837 LOOKUP_MAPPINGS.put("buildingIds", new Lookup ("Room", "BuildingInfo")); 838 LOOKUP_MAPPINGS.put("roomId", new Lookup ("Room", "RoomInfo")); 839 LOOKUP_MAPPINGS.put("roomIds", new Lookup ("Room", "RoomInfo")); 840 LOOKUP_MAPPINGS.put("populationId", new Lookup ("Population", "PopulationInfo")); 841 LOOKUP_MAPPINGS.put("populationIds", new Lookup ("Population", "PopulationInfo")); 842 843 844 // COMMON RICE IDENTITY SERVICE 845 LOOKUP_MAPPINGS.put("principalId", new Lookup ("rice.kim.Identity", "Principal")); 846 LOOKUP_MAPPINGS.put("principalIds", new Lookup ("rice.kim.Identity", "Principal")); 847 // TODO: fix these Ids that currently maps to principal instead of the entity id 848 LOOKUP_MAPPINGS.put("personId", new Lookup ("rice.kim.Identity", "Principal")); 849 LOOKUP_MAPPINGS.put("personIds", new Lookup ("rice.kim.Identity", "Principal")); 850 LOOKUP_MAPPINGS.put("instructorId", new Lookup ("rice.kim.Identity", "Principal")); 851 LOOKUP_MAPPINGS.put("instructorIds", new Lookup ("rice.kim.Identity", "Principal")); 852 LOOKUP_MAPPINGS.put("studentId", new Lookup ("rice.kim.Identity", "Principal")); 853 LOOKUP_MAPPINGS.put("studentIds", new Lookup ("rice.kim.Identity", "Principal")); 854 855 // Common objects 856 // TimeAmount 857 LOOKUP_MAPPINGS.put("atpDurationTypeKey", new Lookup ("Type", "TypeInfo")); 858 LOOKUP_MAPPINGS.put("currencyTypeKey", new Lookup ("Type", "TypeInfo")); 859 // Context 860 LOOKUP_MAPPINGS.put("authenticatedPrincipalId", new Lookup ("rice.kim.Identity", "Principal")); 861 // meta 862 LOOKUP_MAPPINGS.put("createId", new Lookup ("rice.kim.Identity", "Principal")); 863 LOOKUP_MAPPINGS.put("updateId", new Lookup ("rice.kim.Identity", "Principal")); 864 LOOKUP_MAPPINGS.put("agendaId", new Lookup ("rice.krms.Agenda", "Agenda")); 865 LOOKUP_MAPPINGS.put("agendaIds", new Lookup ("rice.krms.Agenda", "Agenda")); 866 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 867 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 868 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 869 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 870 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 871 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 872 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 873 874 875 // TODO: replace or augment this special list of ones with annotations in the contract itself 876 // program service 877 LOOKUP_MAPPINGS.put("unitsContentOwner", new Lookup ("Organization", "OrgInfo")); 878 LOOKUP_MAPPINGS.put("unitsDeployment", new Lookup ("Organization", "OrgInfo")); 879 LOOKUP_MAPPINGS.put("unitsStudentOversight", new Lookup ("Organization", "OrgInfo")); 880 LOOKUP_MAPPINGS.put("unitsFinancialResources", new Lookup ("Organization", "OrgInfo")); 881 LOOKUP_MAPPINGS.put("unitsFinancialControl", new Lookup ("Organization", "OrgInfo")); 882 LOOKUP_MAPPINGS.put("divisionsContentOwner", new Lookup ("Organization", "OrgInfo")); 883 LOOKUP_MAPPINGS.put("divisionsDeployment", new Lookup ("Organization", "OrgInfo")); 884 LOOKUP_MAPPINGS.put("divisionsStudentOversight", new Lookup ("Organization", "OrgInfo")); 885 LOOKUP_MAPPINGS.put("divisionsFinancialResources", new Lookup ("Organization", "OrgInfo")); 886 LOOKUP_MAPPINGS.put("divisionsFinancialControl", new Lookup ("Organization", "OrgInfo")); 887 LOOKUP_MAPPINGS.put("startTerm", new Lookup ("AcademicCalendar", "TermInfo")); 888 LOOKUP_MAPPINGS.put("endTerm", new Lookup ("AcademicCalendar", "TermInfo")); 889 LOOKUP_MAPPINGS.put("endProgramEntryTerm", new Lookup ("AcademicCalendar", "TermInfo")); 890 LOOKUP_MAPPINGS.put("resultOptions", new Lookup ("LRC", "ResultValuesGroupInfo")); 891 LOOKUP_MAPPINGS.put("programRequirements", new Lookup ("Program", "ProgramRequirementInfo")); 892 // share by program and course 893 LOOKUP_MAPPINGS.put("parentRelType", new Lookup ("Type", "TypeInfo")); 894 LOOKUP_MAPPINGS.put("parentLoRelationid", new Lookup ("LearningObjective", "LoInfo")); 895 896 // type service 897 LOOKUP_MAPPINGS.put("ownerTypeKey", new Lookup ("Type", "TypeInfo")); 898 LOOKUP_MAPPINGS.put("relatedTypeKey", new Lookup ("Type", "TypeInfo")); 899 900 // State service (there are no special purpose ones) 901 902 // LRC service (there are no special purpose ones) 903 904 // atp 905 LOOKUP_MAPPINGS.put("adminOrgId", new Lookup ("Organization", "OrgInfo")); 906 LOOKUP_MAPPINGS.put("relatedAtpId", new Lookup ("Atp", "AtpInfo")); 907 LOOKUP_MAPPINGS.put("relativeAnchorMilestoneId", new Lookup ("Atp", "MilestoneInfo")); 908 909 // Lui 910 LOOKUP_MAPPINGS.put("relatedLuiTypes", new Lookup ("Type", "TypeInfo")); 911 LOOKUP_MAPPINGS.put("relatedLuiId", new Lookup ("Lui", "LuiInfo")); 912 913 // Course Offering 914 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 915 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 916 917 // TODO: finish the services 918 LOOKUP_MAPPINGS.put("unitsDeploymentOrgIds", new Lookup ("Organization", "OrgInfo")); 919 LOOKUP_MAPPINGS.put("unitsContentOwnerOrgIds", new Lookup ("Organization", "OrgInfo")); 920 LOOKUP_MAPPINGS.put("unitsContentOwnerId", new Lookup ("Organization", "OrgInfo")); 921 LOOKUP_MAPPINGS.put("jointOfferingIds", new Lookup ("CourseOffering", "CourseOfferingInfo")); 922 LOOKUP_MAPPINGS.put("gradingOptionId", new Lookup ("LRC", "ResultValuesGroupInfo")); 923 LOOKUP_MAPPINGS.put("creditOptionId", new Lookup ("LRC", "ResultValuesGroupInfo")); 924 LOOKUP_MAPPINGS.put("waitlistLevelTypeKey", new Lookup ("Type", "TypeInfo")); 925 LOOKUP_MAPPINGS.put("waitlistTypeKey", new Lookup ("Type", "TypeInfo")); 926 LOOKUP_MAPPINGS.put("activityOfferingTypeKeys", new Lookup ("Type", "TypeInfo")); 927 LOOKUP_MAPPINGS.put("gradeRosterLevelTypeKey", new Lookup ("Type", "TypeInfo")); 928 LOOKUP_MAPPINGS.put("finalExamLevelTypeKey", new Lookup ("Type", "TypeInfo")); 929 LOOKUP_MAPPINGS.put("schedulingStateKey", new Lookup ("State", "StateInfo")); 930 LOOKUP_MAPPINGS.put("gradingOptionKeys", new Lookup ("LRC", "ResultValuesGroupInfo")); 931 LOOKUP_MAPPINGS.put("creditOptionId", new Lookup ("LRC", "ResultValuesGroupInfo")); 932 LOOKUP_MAPPINGS.put("gradingOptionKeys", new Lookup ("", "")); 933 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 934 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 935 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 936 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 937 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 938 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 939 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 940 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 941 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 942 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 943 LOOKUP_MAPPINGS.put("", new Lookup ("", "")); 944 945 } 946 947 private boolean calcOverridden(JavaClass mainClass, JavaMethod getterMethod) { 948 if (getterMethod == null) { 949 return false; 950 } 951 JavaMethod infcGetter = null; 952 if (getterMethod.getParentClass().isInterface()) { 953 infcGetter = getterMethod; 954 } 955 if (infcGetter == null) { 956 infcGetter = findInterfaceMethod(mainClass, getterMethod, false); 957 } 958 if (infcGetter == null) { 959 return false; 960 } 961 Annotation annotation = this.getAnnotation(infcGetter, null, null, "Override"); 962 if (annotation != null) { 963 return true; 964 } 965 return false; 966 } 967 968 private String calcComment(JavaClass javaClass) { 969 return this.calcComment(javaClass.getComment()); 970 } 971 972 private String calcComment(String comment) { 973 return this.parseCommentVersion(comment)[0]; 974 } 975 976 private String calcVersion(JavaClass javaClass) { 977 DocletTag tag = javaClass.getTagByName("version", true); 978 if (tag != null) { 979 return tag.getValue(); 980 } 981 return this.calcVersion(javaClass.getComment()); 982 } 983 984 private String calcVersion(String comment) { 985 return this.parseCommentVersion(comment)[1]; 986 } 987 988 private String[] parseCommentVersion(String commentVersion) { 989 String[] parsed = new String[2]; 990 if (commentVersion == null) { 991 return parsed; 992 } 993 commentVersion = commentVersion.trim(); 994 int i = commentVersion.toLowerCase().indexOf("\nversion:"); 995 if (i == -1) { 996 parsed[0] = commentVersion; 997 return parsed; 998 } 999 parsed[1] = commentVersion.substring(i + "\nversion:".length()).trim(); 1000 parsed[0] = commentVersion.substring(0, i).trim(); 1001 1002 return parsed; 1003 } 1004 1005 private Annotation getAnnotation(JavaMethod getterMethod, 1006 JavaMethod setterMethod, JavaField beanField, String type) { 1007 if (beanField != null) { 1008 1009 for (Annotation annotation : beanField.getAnnotations()) { 1010 if (annotation.getType().getJavaClass().getName().equals(type)) { 1011 return annotation; 1012 } 1013 } 1014 } 1015 if (getterMethod != null) { 1016 1017 for (Annotation annotation : getterMethod.getAnnotations()) { 1018 if (annotation.getType().getJavaClass().getName().equals(type)) { 1019 return annotation; 1020 } 1021 } 1022 } 1023 if (setterMethod != null) { 1024 1025 for (Annotation annotation : setterMethod.getAnnotations()) { 1026 if (annotation.getType().getJavaClass().getName().equals(type)) { 1027 return annotation; 1028 } 1029 } 1030 } 1031 return null; 1032 } 1033 1034 private String calcRequired(JavaMethod getterMethod, 1035 JavaMethod setterMethod, JavaField beanField) { 1036 Annotation annotation = this.getAnnotation(getterMethod, setterMethod, beanField, "XmlElement"); 1037 if (annotation == null) { 1038 annotation = this.getAnnotation(getterMethod, setterMethod, beanField, "XmlAttribute"); 1039 } 1040 if (annotation != null) { 1041 Object required = annotation.getNamedParameter("required"); 1042 if (required != null) { 1043 if (required.toString().equalsIgnoreCase("true")) { 1044 return "Required"; 1045 } 1046 } 1047 } 1048 if (getterMethod != null) { 1049 DocletTag tag = getterMethod.getTagByName("required", true); 1050 if (tag != null) { 1051 if (tag.getValue() == null) { 1052 return "Required"; 1053 } 1054 String required = "Required " + tag.getValue(); 1055 return required.trim(); 1056 } 1057 } 1058 return null; 1059 } 1060 1061 private String calcReadOnly(JavaMethod getterMethod, 1062 JavaMethod setterMethod, JavaField beanField) { 1063 if (getterMethod != null) { 1064 DocletTag tag = getterMethod.getTagByName("readOnly", true); 1065 if (tag != null) { 1066 if (tag.getValue() == null) { 1067 return "Read only"; 1068 } 1069 String readOnly = "Read only " + tag.getValue(); 1070 return readOnly.trim(); 1071 } 1072 } 1073 return null; 1074 } 1075 1076 private String calcImplementationNotes(JavaMethod serviceMethod) { 1077 StringBuilder bldr = new StringBuilder(); 1078 String newLine = ""; 1079 for (DocletTag tag : serviceMethod.getTagsByName("impl", true)) { 1080 bldr.append(newLine); 1081 newLine = "\n"; 1082 String value = tag.getValue(); 1083 bldr.append(value); 1084 } 1085 if (hasOverride(serviceMethod)) { 1086 boolean matchJustOnName = true; 1087 JavaMethod overriddenMethod = findInterfaceMethod(serviceMethod.getParentClass(), serviceMethod, matchJustOnName); 1088 if (overriddenMethod == null) { 1089 // do it again so we can debug 1090 findInterfaceMethod(serviceMethod.getParentClass(), serviceMethod, true); 1091 throw new NullPointerException("could not find overridden method or method that has @Override annotation " + serviceMethod.getCallSignature()); 1092 } 1093 bldr.append(newLine); 1094 newLine = "\n"; 1095 bldr.append("Overridden method should be implemented in helper: "); 1096 bldr.append(overriddenMethod.getParentClass().getName()); 1097 } 1098 if (bldr.length() == 0) { 1099 return null; 1100 } 1101 return bldr.toString(); 1102 } 1103 1104 private boolean hasOverride(JavaMethod serviceMethod) { 1105 for (Annotation annotation : serviceMethod.getAnnotations()) { 1106 if (annotation.getType().getJavaClass().getName().equals( 1107 "Override")) { 1108 return true; 1109 } 1110 } 1111 return false; 1112 } 1113 1114 private boolean isDeprecated(JavaMethod serviceMethod) { 1115 for (Annotation annotation : serviceMethod.getAnnotations()) { 1116 if (annotation.getType().getJavaClass().getName().equals( 1117 "Deprecated")) { 1118 return true; 1119 } 1120 } 1121 return false; 1122 } 1123 1124 private String calcImplementationNotes(JavaMethod getterMethod, 1125 JavaMethod setterMethod, JavaField beanField) { 1126 if (getterMethod != null) { 1127 DocletTag tag = getterMethod.getTagByName("impl", true); 1128 if (tag != null) { 1129 return tag.getValue(); 1130 } 1131 } 1132 return null; 1133 } 1134 1135 private String calcNameFromShortName(String shortName) { 1136 StringBuilder bldr = new StringBuilder(shortName.length() + 3); 1137 char c = shortName.charAt(0); 1138 bldr.append(Character.toUpperCase(c)); 1139 boolean lastWasUpper = true; 1140 for (int i = 1; i < shortName.length(); i++) { 1141 c = shortName.charAt(i); 1142 if (Character.isUpperCase(c)) { 1143 if (!lastWasUpper) { 1144 bldr.append(" "); 1145 } 1146 } else { 1147 lastWasUpper = false; 1148 } 1149 bldr.append(c); 1150 } 1151 return bldr.toString(); 1152 } 1153 1154 private String calcName(JavaClass mainClass, JavaMethod getterMethod, 1155 JavaMethod setterMethod, JavaField beanField, String shortName) { 1156 String name = this.calcNameFromTag(getterMethod, setterMethod, beanField); 1157 if (name != null) { 1158 return name; 1159 } 1160 name = this.calcNameFromNameEmbeddedInDescription(mainClass, getterMethod, setterMethod, beanField, shortName); 1161 if (name != null) { 1162 return name; 1163 } 1164 return this.calcNameFromShortName(shortName); 1165 } 1166 1167 private String calcNameFromTag(JavaMethod getterMethod, 1168 JavaMethod setterMethod, JavaField beanField) { 1169 if (getterMethod != null) { 1170 DocletTag tag = getterMethod.getTagByName("name", true); 1171 if (tag != null) { 1172 return tag.getValue(); 1173 } 1174 } 1175 return null; 1176 } 1177 1178 private String calcNameFromNameEmbeddedInDescription(JavaClass mainClass, JavaMethod getterMethod, 1179 JavaMethod setterMethod, JavaField beanField, String shortName) { 1180 String nameDesc = this.calcMethodComment(mainClass, getterMethod, setterMethod, 1181 beanField, shortName); 1182 String[] parsed = parseNameDesc(nameDesc); 1183 return parsed[0]; 1184 } 1185 1186 private String[] parseNameDesc(String nameDesc) { 1187 String[] parsed = new String[2]; 1188 if (nameDesc == null) { 1189 return parsed; 1190 } 1191 nameDesc = nameDesc.trim(); 1192 if (!nameDesc.startsWith("Name:")) { 1193 parsed[1] = nameDesc; 1194 return parsed; 1195 } 1196 nameDesc = nameDesc.substring("Name:".length()).trim(); 1197 int i = nameDesc.indexOf("\n"); 1198 if (i == -1) { 1199 parsed[0] = nameDesc.trim(); 1200 return parsed; 1201 } 1202 parsed[0] = nameDesc.substring(0, i).trim(); 1203 parsed[1] = nameDesc.substring(i).trim(); 1204 return parsed; 1205 } 1206 1207 private String calcDescription(JavaClass mainClass, JavaMethod getterMethod, 1208 JavaMethod setterMethod, JavaField beanField, String shortName) { 1209 String nameDesc = this.calcMethodComment(mainClass, getterMethod, setterMethod, 1210 beanField, shortName); 1211 String[] parsed = parseNameDesc(nameDesc); 1212 return parsed[1]; 1213 } 1214 1215 private String calcMethodComment(JavaClass mainClass, JavaMethod getterMethod, 1216 JavaMethod setterMethod, 1217 JavaField beanField, 1218 String shortName) { 1219 String desc = null; 1220 if (getterMethod != null) { 1221 desc = getterMethod.getComment(); 1222 if (isCommentNotEmpty(desc)) { 1223 return desc; 1224 } 1225 // System.out.println("Searching for superclass to find description for field " + shortName); 1226 JavaClass jc = mainClass; 1227 while (true) { 1228 JavaClass superJc = jc.getSuperJavaClass(); 1229 if (superJc == null) { 1230 break; 1231 } 1232 JavaMethod parentGetterMethod = this.findGetterMethod(superJc, shortName); 1233 if (parentGetterMethod != null) { 1234 desc = parentGetterMethod.getComment(); 1235 if (isCommentNotEmpty(desc)) { 1236 return desc; 1237 } 1238 } 1239 jc = superJc; 1240 } 1241 } 1242 if (setterMethod != null) { 1243 desc = setterMethod.getComment(); 1244 if (isCommentNotEmpty(desc)) { 1245 return desc; 1246 } 1247 } 1248 if (beanField != null) { 1249 desc = beanField.getComment(); 1250 if (isCommentNotEmpty(desc)) { 1251 return desc; 1252 } 1253 } 1254 desc = calcMethodCommentRecursively(mainClass, getterMethod); 1255 if (isCommentNotEmpty(desc)) { 1256 return desc; 1257 } 1258 desc = calcMethodCommentRecursively(mainClass, setterMethod); 1259 if (isCommentNotEmpty(desc)) { 1260 return desc; 1261 } 1262 return null; 1263 } 1264 1265 private String calcMethodCommentRecursively(JavaClass mainClass, JavaMethod method) { 1266 if (method == null) { 1267 return null; 1268 } 1269 String desc = method.getComment(); 1270 if (isCommentNotEmpty(desc)) { 1271 return desc; 1272 } 1273 JavaMethod infcMethod = findInterfaceMethod(mainClass, method, false); 1274 if (infcMethod != null) { 1275 desc = infcMethod.getComment(); 1276 if (isCommentNotEmpty(desc)) { 1277 return desc; 1278 } 1279 } 1280 JavaMethod superMethod = findSuperMethod(method); 1281 if (superMethod != null) { 1282 desc = superMethod.getComment(); 1283 if (isCommentNotEmpty(desc)) { 1284 return desc; 1285 } 1286 } 1287 return null; 1288 } 1289 1290 private JavaMethod findSuperMethod(JavaMethod method) { 1291 // System.out.println("Searching for super method for " 1292 // + method.getParentClass().getName() + "." 1293 // + method.getCallSignature()); 1294 for (JavaMethod superMethod : method.getParentClass().getMethods(true)) { 1295 if (method.equals(superMethod)) { 1296 continue; 1297 } 1298 if (method.getCallSignature().equals(superMethod.getCallSignature())) { 1299 return superMethod; 1300 } 1301 } 1302 return null; 1303 } 1304 1305 private JavaMethod findInterfaceMethod(JavaClass mainClass, JavaMethod method, boolean matchJustOnName) { 1306 String callSig = method.getCallSignature(); 1307 if (matchJustOnName) { 1308 callSig = method.getName(); 1309 } 1310 JavaClass classToSearch = mainClass; 1311 // log ("Searching mainClass " + classToSearch.getName() + " for " + callSig, callSig); 1312 while (true) { 1313 for (JavaClass infcClass : classToSearch.getImplementedInterfaces()) { 1314 JavaMethod meth = this.findMethodOnInterfaceRecursively(infcClass, callSig, matchJustOnName); 1315 if (meth != null) { 1316 // recursionCntr = 0; 1317 return meth; 1318 } 1319 } 1320 JavaClass superClass = classToSearch.getSuperJavaClass(); 1321 if (superClass == null) { 1322 // recursionCntr = 0; 1323 // log ("Did not find " + callSig + " on " + mainClass, callSig); 1324 return null; 1325 } 1326 classToSearch = superClass; 1327 // log ("Searching superClass " + classToSearch.getName() + " for " + callSig, callSig); 1328 } 1329 } 1330 1331 // private void log (String message, String callSig) { 1332 // if (callSig.equalsIgnoreCase("getTypeKey()")) { 1333 // for (int i = 0; i < this.recursionCntr; i++) { 1334 // System.out.print (" "); 1335 // } 1336 // System.out.println (message); 1337 // } 1338 // } 1339 // private int recursionCntr = 0; 1340 private JavaMethod findMethodOnInterfaceRecursively(JavaClass infcClass, String callSig, boolean matchJustOnName) { 1341 // recursionCntr++; 1342 // log ("Searching interface " + infcClass.getName() + " for " + callSig, callSig); 1343 for (JavaMethod infcMethod : infcClass.getMethods()) { 1344 if (callSig.equals(infcMethod.getCallSignature())) { 1345 // log (callSig + " found on " + infcClass.getName() + "!!!!!!!!!!!!!!!!", callSig); 1346 // recursionCntr--; 1347 return infcMethod; 1348 } 1349 if (matchJustOnName) { 1350 if (callSig.equals(infcMethod.getName())) { 1351 return infcMethod; 1352 } 1353 } 1354 } 1355 for (JavaClass subInfc : infcClass.getImplementedInterfaces()) { 1356 // log ("Searching sub-interface " + subInfc.getName() + " for " + callSig, callSig); 1357 JavaMethod infcMethod = findMethodOnInterfaceRecursively(subInfc, callSig, matchJustOnName); 1358 if (infcMethod != null) { 1359 // recursionCntr--; 1360 return infcMethod; 1361 } 1362 } 1363 // log (callSig + " not found on " + infcClass.getName(), callSig); 1364 // this.recursionCntr--; 1365 return null; 1366 } 1367 1368 private boolean isCommentNotEmpty(String desc) { 1369 if (desc == null) { 1370 return false; 1371 } 1372 if (desc.trim().isEmpty()) { 1373 return false; 1374 } 1375 if (desc.contains("@inheritDoc")) { 1376 return false; 1377 } 1378 return true; 1379 } 1380 1381 private String getAccessorType(JavaMethod method) { 1382 String accessorType = getAccessorType(method.getAnnotations()); 1383 if (accessorType != null) { 1384 return accessorType; 1385 } 1386 accessorType = getAccessorType(method.getParentClass().getAnnotations()); 1387 return accessorType; 1388 } 1389 1390 private String getAccessorType(Annotation[] annotations) { 1391 for (Annotation annotation : annotations) { 1392 if (annotation.getType().getJavaClass().getName().equals( 1393 "XmlAccessorType")) { 1394 // System.out.println ("Looking for XmlAccessorType annotation = " 1395 // + annotation.getParameterValue ()); 1396 return annotation.getParameterValue().toString(); 1397 } 1398 } 1399 return null; 1400 } 1401 1402 private String stripQuotes(String str) { 1403 if (str.startsWith("\"")) { 1404 str = str.substring(1); 1405 } 1406 if (str.endsWith("\"")) { 1407 str = str.substring(0, str.length() - 1); 1408 } 1409 return str; 1410 } 1411 1412 private String calcMissing(String str) { 1413 if (str == null) { 1414 return "???"; 1415 } 1416 if (str.trim().isEmpty()) { 1417 return "???"; 1418 } 1419 return str; 1420 } 1421 1422 private void addServiceToList(XmlType xmlType, String serviceKey) { 1423 if (!xmlType.getService().contains(serviceKey)) { 1424 xmlType.setService(xmlType.getService() + ", " + serviceKey); 1425 } 1426 } 1427 1428 private String calcXmlAttribute(JavaField beanField) { 1429 if (beanField == null) { 1430 // TODO: worry about checking for this annotation on the method for non-field based AccessorTypes 1431 return "No"; 1432 } 1433 for (Annotation annotation : beanField.getAnnotations()) { 1434 if (annotation.getType().getJavaClass().getName().equals("XmlAttribute")) { 1435 return "Yes"; 1436 } 1437 } 1438 return "No"; 1439 } 1440 1441 private JavaField findField(JavaClass javaClass, String shortName, 1442 JavaMethod setterMethod) { 1443 JavaField field = findField(javaClass, shortName); 1444 if (field != null) { 1445 return field; 1446 } 1447 if (setterMethod != null) { 1448 String paramName = setterMethod.getParameters()[0].getName(); 1449 if (paramName.equalsIgnoreCase(shortName)) { 1450 return null; 1451 } 1452 return findField(javaClass, paramName); 1453 } 1454 return null; 1455 } 1456 1457 private JavaField findField(JavaClass javaClass, String name) { 1458 if (name == null) { 1459 return null; 1460 } 1461 for (JavaField field : javaClass.getFields()) { 1462 if (field.getName().equalsIgnoreCase(name)) { 1463 return field; 1464 } 1465 // TODO: check for shortNames that already start with is so we don't check for isIsEnrollable 1466 if (field.getName().equals("is" + name)) { 1467 return field; 1468 } 1469 } 1470 JavaClass superClass = javaClass.getSuperJavaClass(); 1471 if (superClass == null) { 1472 return null; 1473 } 1474 return findField(superClass, name); 1475 } 1476 1477 private JavaMethod findGetterMethod(JavaClass msClass, String shortName) { 1478 for (JavaMethod method : msClass.getMethods(true)) { 1479 String methodName = method.getName(); 1480 if (methodName.equalsIgnoreCase("get" + shortName)) { 1481 return method; 1482 } 1483 if (methodName.toLowerCase().startsWith("is")) { 1484 if (methodName.equalsIgnoreCase("is" + shortName)) { 1485 return method; 1486 } 1487 // shortName already has "is" in it 1488 if (methodName.equalsIgnoreCase(shortName)) { 1489 return method; 1490 } 1491 } 1492 // TODO: followup on KimEntityResidencyInfo.getInState 1493 if (methodName.equalsIgnoreCase("getInState") && shortName.equalsIgnoreCase( 1494 "InStateFlag")) { 1495 return method; 1496 } 1497 } 1498 return null; 1499 } 1500 1501 private JavaMethod findSetterMethod(JavaClass msClass, String shortName) { 1502 for (JavaMethod method : msClass.getMethods(true)) { 1503 if (method.getName().equals("set" + shortName)) { 1504 return method; 1505 } 1506 // TODO: check for shortNames that already start with is so we don't check for isIsEnrollable 1507 if (method.getName().equals("setIs" + shortName)) { 1508 return method; 1509 } 1510 // TODO: followup on KimEntityResidencyInfo.getInState 1511 if (method.getName().equals("setInStateFlag") && shortName.equals( 1512 "InState")) { 1513 return method; 1514 } 1515 } 1516 return null; 1517 } 1518 private static final String[] SETTER_METHODS_TO_SKIP = { 1519 // Somebody put "convenience" methods on the validation result info 1520 "ValidationResultInfo.setWarning", 1521 "ValidationResultInfo.setError", 1522 // not on original wiki but still defined as a method but not backed by a field so not in wsdl 1523 "CredentialProgramInfo.setDiplomaTitle", 1524 // synonym for the official of setCredentialType 1525 "CredentialProgramInfo.setType", 1526 // not on original wiki but still defined as a method but not backed by a field so not in wsdl 1527 "CredentialProgramInfo.setHegisCode", 1528 "CredentialProgramInfo.setCip2000Code", 1529 "CredentialProgramInfo.setCip2010Code", 1530 "CredentialProgramInfo.setSelectiveEnrollmentCode", 1531 "CoreProgramInfo.setDiplomaTitle", 1532 // synonym for the official of setCredentialType 1533 // "CoreProgramInfo.setType", 1534 // not on original wiki but still defined as a method but not backed by a field so not in wsdl 1535 "CoreProgramInfo.setHegisCode", 1536 "CoreProgramInfo.setCip2000Code", 1537 "CoreProgramInfo.setCip2010Code", 1538 "CoreProgramInfo.setSelectiveEnrollmentCode", 1539 "WhenConstraint.setValue" 1540 }; 1541 private static final String[] GETTER_METHODS_TO_SKIP = { 1542 // Somebody put "convenience" methods on the validation result info 1543 "ValidationResultInfo.getWarning", 1544 "ValidationResultInfo.getError", 1545 // not on original wiki but still defined as a method but not backed by a field so not in wsdl 1546 "CredentialProgramInfo.getDiplomaTitle", 1547 // synonym for the official of setCredentialType 1548 "CredentialProgramInfo.getType", 1549 // not on original wiki but still defined as a method but not backed by a field so not in wsdl 1550 "CredentialProgramInfo.getHegisCode", 1551 "CredentialProgramInfo.getCip2000Code", 1552 "CredentialProgramInfo.getCip2010Code", 1553 "CredentialProgramInfo.getSelectiveEnrollmentCode", 1554 "CoreProgramInfo.getDiplomaTitle", 1555 // synonym for the official of setCredentialType 1556 // "CoreProgramInfo.setType", 1557 // not on original wiki but still defined as a method but not backed by a field so not in wsdl 1558 "CoreProgramInfo.getHegisCode", 1559 "CoreProgramInfo.getCip2000Code", 1560 "CoreProgramInfo.getCip2010Code", 1561 "CoreProgramInfo.getSelectiveEnrollmentCode", 1562 "WhenConstraint.getValue" 1563 }; 1564 1565 private boolean isSetterMethodToProcess(JavaMethod method, String className) { 1566 if (!method.getName().startsWith("set")) { 1567 return false; 1568 } 1569 if (method.getParameters().length != 1) { 1570 return false; 1571 } 1572 if (method.isPrivate()) { 1573 return false; 1574 } 1575 if (method.isProtected()) { 1576 return false; 1577 } 1578 if (method.isStatic()) { 1579 return false; 1580 } 1581 if (method.getParentClass().getPackageName().startsWith("java")) { 1582 return false; 1583 } 1584 String fullName = className + "." + method.getName(); 1585 for (String skip : SETTER_METHODS_TO_SKIP) { 1586 if (skip.equals(fullName)) { 1587 return false; 1588 } 1589 } 1590 // if (method.getParentClass ().isInterface ()) 1591 // { 1592 // return false; 1593 // } 1594 for (Annotation annotation : method.getAnnotations()) { 1595 if (annotation.getType().getJavaClass().getName().equals("XmlTransient")) { 1596 return false; 1597 } 1598 } 1599 return true; 1600 } 1601 1602 private boolean isGetterMethodToProcess(JavaMethod method, String className) { 1603 if (!method.getName().startsWith("get")) { 1604 if (!method.getName().startsWith("is")) { 1605 return false; 1606 } 1607 } 1608 if (method.getParameters().length != 0) { 1609 return false; 1610 } 1611 if (method.isPrivate()) { 1612 return false; 1613 } 1614 if (method.isProtected()) { 1615 return false; 1616 } 1617 if (method.isStatic()) { 1618 return false; 1619 } 1620 if (method.getParentClass().getPackageName().startsWith("java")) { 1621 return false; 1622 } 1623 String fullName = className + "." + method.getName(); 1624 for (String skip : GETTER_METHODS_TO_SKIP) { 1625 if (skip.equals(fullName)) { 1626 return false; 1627 } 1628 } 1629 // if (method.getParentClass ().isInterface ()) 1630 // { 1631 // return false; 1632 // } 1633 for (Annotation annotation : method.getAnnotations()) { 1634 if (annotation.getType().getJavaClass().getName().equals("XmlTransient")) { 1635 return false; 1636 } 1637 } 1638 return true; 1639 } 1640 1641 private String calcShortNameFromSetter(JavaMethod method) { 1642 return method.getName().substring(3); 1643 } 1644 1645 private String calcShortNameFromGetter(JavaMethod method) { 1646 if (method.getName().startsWith("get")) { 1647 return method.getName().substring(3); 1648 } 1649 if (method.getName().startsWith("is")) { 1650 return method.getName().substring(2); 1651 } 1652 throw new IllegalArgumentException(method.getName() 1653 + " does not start with is or get"); 1654 } 1655 1656 private String calcCardinality(JavaClass mainClass, JavaMethod getterMethod, 1657 JavaMethod setterMethod, JavaField beanField, String shortName) { 1658 if (isReturnACollection(mainClass, getterMethod, setterMethod, beanField, shortName)) { 1659 return "Many"; 1660 } 1661 return "One"; 1662 } 1663 1664 private boolean isReturnACollection(JavaClass mainClass, JavaMethod getterMethod, 1665 JavaMethod setterMethod, JavaField beanField, String shortName) { 1666 if (getterMethod != null) { 1667 return isCollection(getterMethod.getReturnType()); 1668 } 1669 if (beanField != null) { 1670 return isCollection(beanField.getType()); 1671 } 1672 // TODO: check setterMethod 1673 return false; 1674 } 1675 1676 private boolean isCollection(Type type) { 1677 JavaClass javaClass = type.getJavaClass(); 1678 return this.isCollection(javaClass); 1679 } 1680 1681 private boolean isCollection(JavaClass javaClass) { 1682 if (javaClass.getName().equals("LocalKeyList")) { 1683 return true; 1684 } 1685 if (javaClass.getName().equals("MessageGroupKeyList")) { 1686 return true; 1687 } 1688 if (javaClass.getName().equals(List.class.getSimpleName())) { 1689 return true; 1690 } 1691 if (javaClass.getName().equals(ArrayList.class.getSimpleName())) { 1692 return true; 1693 } 1694 if (javaClass.getName().equals(Collection.class.getSimpleName())) { 1695 return true; 1696 } 1697 if (javaClass.getName().equals(Set.class.getSimpleName())) { 1698 return true; 1699 } 1700 return false; 1701 } 1702 1703 private String calcType(JavaClass mainClass, JavaMethod getterMethod, 1704 JavaMethod setterMethod, JavaField beanField, String shortName) { 1705 if (getterMethod != null) { 1706 return calcTypeOfGetterMethodReturn(getterMethod); 1707 } 1708 if (beanField != null) { 1709 Type type = beanField.getType(); 1710 return calcType(type); 1711 } 1712 // TODO: calc type based on the setterMethod 1713 return null; 1714 } 1715 1716 private String calcTypeOfGetterMethodReturn(JavaMethod getterMethod) { 1717 Type type = getterMethod.getReturnType(); 1718 return calcType(type); 1719 } 1720 1721 private String calcType(Type type) { 1722 if (type == null) { 1723 return "void"; 1724 } 1725 if (isCollection(type.getJavaClass())) { 1726 return calcType(calcRealJavaClass(type)) + "List"; 1727 } 1728 return calcType(calcRealJavaClass(type)); 1729 } 1730 1731 private Annotation findJavaAnnotation(String name, JavaClass clazz) { 1732 1733 Annotation[] annotations = clazz.getAnnotations(); 1734 1735 for (Annotation annotation : annotations) { 1736 1737 if (annotation.getType().getJavaClass().getName().equals(name)) { 1738 return annotation; 1739 } 1740 } 1741 return null; 1742 } 1743 private String calcType(JavaClass javaClass) { 1744 1745 if (javaClass.isEnum()) { 1746 1747 if (!JavaClassAnnotationUtils.doesAnnotationExist( 1748 XmlEnum.class.getSimpleName(), javaClass)) { 1749 // a rice or other dependency without the @XmlEnum annotation 1750 // present 1751 if (javaClass.getName().equals("WriteAccess")) { 1752 // rice CommonLookupParam 1753 return "String"; 1754 } else if (javaClass.getName().equals("Widget")) { 1755 // rice CommonLookupParam 1756 return "String"; 1757 } else if (javaClass.getName().equals("Usage")) { 1758 // rice 1759 return "String"; 1760 } else { 1761 // this allows the types to be manually specified 1762 // using the full package.classname format. 1763 return javaClass.getFullyQualifiedName(); 1764 } 1765 1766 } 1767 1768 Class<?>annotationSpecifiedType = JavaClassAnnotationUtils.extractXmlEnumValue(javaClass); 1769 1770 return annotationSpecifiedType.getSimpleName(); 1771 1772 } 1773 // this is messed up instead of list of strings it is an object with a list of strings 1774 if (javaClass.getName().equals(LOCALE_KEY_LIST)) { 1775 return "StringList"; 1776 } 1777 if (javaClass.getName().equals(MESSAGE_GROUP_KEY_LIST)) { 1778 return "StringList"; 1779 } 1780 // TODO: figure out why rice stuff translates like this junk? 1781 if (javaClass.getName().equals("java$util$Map")) { 1782 return "Map<String, String>"; 1783 } 1784 if (javaClass.getName().equals("Map")) { 1785 // TODO: make sure it is in fact a String,String map 1786 return "Map<String, String>"; 1787 } 1788 return javaClass.getName(); 1789 } 1790 1791 private JavaClass calcRealJavaClassOfGetterReturn(JavaMethod getterMethod) { 1792 if (getterMethod == null) { 1793 return null; 1794 } 1795 Type type = getterMethod.getReturnType(); 1796 return this.calcRealJavaClass(type); 1797 } 1798 1799 private JavaClass calcRealJavaClass(Type type) { 1800 if (type == null) { 1801 return null; 1802 } 1803 JavaClass javaClass = type.getJavaClass(); 1804 if (javaClass.getName().equals(LOCALE_KEY_LIST)) { 1805 return STRING_JAVA_CLASS; 1806 } 1807 if (javaClass.getName().equals(MESSAGE_GROUP_KEY_LIST)) { 1808 return STRING_JAVA_CLASS; 1809 } 1810 if (!this.isCollection(javaClass)) { 1811 return javaClass; 1812 } 1813 1814 // for (Type t : type.getActualTypeArguments ()) 1815 // { 1816 // System.out.println ("ServiceContractModelQDoxLoader: type arguments = " 1817 // + t.toString ()); 1818 // } 1819 1820 Type[]collectionTypeArguments = type.getActualTypeArguments(); 1821 1822 if (collectionTypeArguments == null) 1823 return new JavaClass (Object.class.getName()); 1824 else 1825 return collectionTypeArguments[0].getJavaClass(); 1826 } 1827 1828 private boolean isComplex(JavaClass javaClass) { 1829 if (javaClass.getName().equals ("void")) { 1830 return false; 1831 } 1832 if (javaClass.isEnum()) { 1833 return false; 1834 } 1835 if (javaClass.getName().equals(String.class.getSimpleName())) { 1836 return false; 1837 } 1838 if (javaClass.getName().equals(Integer.class.getSimpleName())) { 1839 return false; 1840 } 1841 if (javaClass.getName().equals(Date.class.getSimpleName())) { 1842 return false; 1843 } 1844 if (javaClass.getName().equals(Long.class.getSimpleName())) { 1845 return false; 1846 } 1847 if (javaClass.getName().equals(Boolean.class.getSimpleName())) { 1848 return false; 1849 } 1850 if (javaClass.getName().equals(Double.class.getSimpleName())) { 1851 return false; 1852 } 1853 if (javaClass.getName().equals(Float.class.getSimpleName())) { 1854 return false; 1855 } 1856 if (javaClass.getName().equals(int.class.getSimpleName())) { 1857 return false; 1858 } 1859 if (javaClass.getName().equals(long.class.getSimpleName())) { 1860 return false; 1861 } 1862 if (javaClass.getName().equals(boolean.class.getSimpleName())) { 1863 return false; 1864 } 1865 if (javaClass.getName().equals(double.class.getSimpleName())) { 1866 return false; 1867 } 1868 if (javaClass.getName().equals(float.class.getSimpleName())) { 1869 return false; 1870 } 1871 if (javaClass.getName().equals(Map.class.getSimpleName())) { 1872 return false; 1873 } 1874 1875 if (javaClass.getName().equals(String.class.getName())) { 1876 return false; 1877 } 1878 if (javaClass.getName().equals(Integer.class.getName())) { 1879 return false; 1880 } 1881 if (javaClass.getName().equals(Date.class.getName())) { 1882 return false; 1883 } 1884 if (javaClass.getName().equals(Long.class.getName())) { 1885 return false; 1886 } 1887 if (javaClass.getName().equals(Boolean.class.getName())) { 1888 return false; 1889 } 1890 if (javaClass.getName().equals(Double.class.getName())) { 1891 return false; 1892 } 1893 if (javaClass.getName().equals(Float.class.getName())) { 1894 return false; 1895 } 1896 if (javaClass.getName().equals(int.class.getName())) { 1897 return false; 1898 } 1899 if (javaClass.getName().equals(long.class.getName())) { 1900 return false; 1901 } 1902 if (javaClass.getName().equals(boolean.class.getName())) { 1903 return false; 1904 } 1905 if (javaClass.getName().equals(double.class.getName())) { 1906 return false; 1907 } 1908 if (javaClass.getName().equals(float.class.getName())) { 1909 return false; 1910 } 1911 if (javaClass.getName().equals(BigDecimal.class.getSimpleName())) { 1912 return false; 1913 } 1914 if (javaClass.getName().equals(Map.class.getName())) { 1915 return false; 1916 } 1917 if (javaClass.getName().equals(LOCALE_KEY_LIST)) { 1918 return false; 1919 } 1920 if (javaClass.getName().equals(MESSAGE_GROUP_KEY_LIST)) { 1921 return false; 1922 } 1923 if (javaClass.getName().equals("java$util$Map")) { 1924 return false; 1925 } 1926 return true; 1927 } 1928 1929 @Override 1930 public String toString() { 1931 return "ServiceContractModelQDoxLoader{" + 1932 "sourceDirectories=" + sourceDirectories + 1933 ", services=" + services + 1934 ", serviceMethods=" + serviceMethods + 1935 ", xmlTypeMap=" + xmlTypeMap + 1936 ", messageStructures=" + messageStructures + 1937 ", validateKualiStudent=" + validateKualiStudent + 1938 '}'; 1939 } 1940 }