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