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