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