001 /* 002 * Copyright 2011 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.Date; 022 import java.util.HashMap; 023 import java.util.HashSet; 024 import java.util.List; 025 import java.util.Map; 026 import java.util.Set; 027 028 import org.junit.After; 029 import org.junit.AfterClass; 030 import org.junit.Before; 031 import org.junit.BeforeClass; 032 import org.junit.Test; 033 034 import static org.junit.Assert.*; 035 036 import org.junit.Ignore; 037 import org.kuali.student.contract.model.MessageStructure; 038 import org.kuali.student.contract.model.Service; 039 import org.kuali.student.contract.model.ServiceContractModel; 040 import org.kuali.student.contract.model.ServiceMethod; 041 import org.kuali.student.contract.model.ServiceMethodParameter; 042 import org.kuali.student.contract.model.XmlType; 043 import org.kuali.student.contract.model.util.HtmlContractMessageStructureWriter; 044 import org.kuali.student.contract.model.util.ModelFinder; 045 import org.kuali.student.contract.model.validation.ServiceContractModelValidator; 046 import org.kuali.student.validation.decorator.mojo.ValidationDecoratorWriterForOneService; 047 import org.slf4j.Logger; 048 import org.slf4j.LoggerFactory; 049 050 /** 051 * 052 * @author nwright 053 */ 054 @Ignore 055 public class R1R2ServiceContractComparisonTest { 056 057 private static Logger log = LoggerFactory.getLogger(R1R2ServiceContractComparisonTest.class); 058 059 060 public R1R2ServiceContractComparisonTest() { 061 } 062 063 @BeforeClass 064 public static void setUpClass() throws Exception { 065 } 066 067 @AfterClass 068 public static void tearDownClass() throws Exception { 069 } 070 071 @Before 072 public void setUp() { 073 074 log.info("This section was created by programmatically comparing the message structures."); 075 log.info("Run on: " + new Date()); 076 log.info("See [R1R2ServiceContractComparisonTest.java|https://test.kuali.org/svn/student/tools/maven-kscontractdoc-plugin/trunk/src/test/java/org/kuali/student/contract/model/impl/R1R2ServiceContractComparisonTest.java]"); 077 log.info(""); 078 log.info("*TABLE OF CONTENTS*"); 079 log.info("{toc}"); 080 log.info(""); 081 log.info("h1. Loading models of the contracts from the source code"); 082 log.info("h2. Log from loading model for R1"); 083 getModel1(); 084 log.info("h2. Log from loading model for R2"); 085 getModel2(); 086 getFinder1(); 087 getFinder2(); 088 loadKnownObjectRenames(); 089 loadKnownUnconvertedObjects(); 090 loadKnownFieldRenames(); 091 loadKnownFieldIssues(); 092 loadKnownMethodRenames(); 093 loadKnownMethodIssues (); 094 } 095 096 @After 097 public void tearDown() { 098 } 099 private static final String RESOURCES_DIRECTORY = "src/test/resources"; 100 private static final String TEST_SOURCE_DIRECTORY = 101 "src/test/java/org/kuali/student/contract/model/test/source"; 102 private static final String ENROLL_PROJECT_SRC_MAIN = "C:/svn/ks-1.3-services/ks-enroll/ks-enroll-api/src/main"; 103 private static final String ENROLL_PROJECT_JAVA_DIRECTORY = ENROLL_PROJECT_SRC_MAIN + "/java"; 104 private static final String RICE_CORE_API_DIRECTORY = "C:/svn/rice/trunk/core/api/src/main/java"; 105 private static final String RICE_KIM_API_DIRECTORY = "C:/svn/rice/trunk/kim/kim-api/src/main/java"; 106 private static final String RICE_LOCATION_API_DIRECTORY = "C:/svn/rice/trunk/location/api/src/main/java"; 107 private static final String RICE_KEW_API_DIRECTORY = "C:/svn/rice/trunk/kew/api/src/main/java"; 108 private static final String RICE_KEN_API_DIRECTORY = "C:/svn/rice/trunk/ken/api/src/main/java"; 109 private static final String RICE_KSB_API_DIRECTORY = "C:/svn/rice/trunk/ksb/api/src/main/java"; 110 private static final String RICE_KRMS_API_DIRECTORY = "C:/svn/rice/trunk/krms/api/src/main/java"; 111 private static final String R1_PROJECT_DIRECTORY = "C:/svn/student/"; 112 private static final String CORE_API_DIRECTORY = R1_PROJECT_DIRECTORY + "ks-core/ks-core-api/src/main/java"; 113 private static final String COMMON_API_DIRECTORY = R1_PROJECT_DIRECTORY + "ks-common/ks-common-api/src/main/java"; 114 private static final String LUM_API_DIRECTORY = R1_PROJECT_DIRECTORY + "ks-lum/ks-lum-api/src/main/java"; 115 private static ServiceContractModel model1 = null; 116 private static ServiceContractModel model2 = null; 117 118 /** 119 * Test of getServiceMethods method, of class ServiceContractModelQDoxLoader. 120 */ 121 @Test 122 public void testCompareModels() { 123 log.info(""); 124 log.info("h1. Message Structure Comparison"); 125 compareTypes(); 126 log.info(""); 127 log.info("h1. Service Method Comparison"); 128 compareMethods(); 129 } 130 131 private ServiceContractModel getModel1() { 132 if (model1 != null) { 133 return model1; 134 } 135 List<String> srcDirs = new ArrayList(); 136 log.info("User directory=" + System.getProperty("user.dir")); 137 log.info("Current directory=" + new File(".").getAbsolutePath()); 138 srcDirs.add(COMMON_API_DIRECTORY); 139 srcDirs.add(CORE_API_DIRECTORY); 140 srcDirs.add(LUM_API_DIRECTORY); 141 log.info ("Reading as input:"); 142 for (String directory : srcDirs) { 143 log.info ("* " + directory); 144 } 145 log.info (""); 146 boolean validateKualiStudent = false; 147 ServiceContractModel instance = new ServiceContractModelQDoxLoader(srcDirs, validateKualiStudent); 148 149 instance = new ServiceContractModelCache(instance); 150 validate(instance); 151 model1 = instance; 152 return instance; 153 } 154 155 private ServiceContractModel getModel2() { 156 if (model2 != null) { 157 return model2; 158 } 159 List<String> srcDirs = new ArrayList(); 160 log.info("User directory=" + System.getProperty("user.dir")); 161 log.info("Current directory=" + new File(".").getAbsolutePath()); 162 srcDirs.add(ENROLL_PROJECT_JAVA_DIRECTORY); 163 log.info ("Reading as input:"); 164 for (String directory : srcDirs) { 165 log.info ("* " + directory); 166 } 167 log.info (""); 168 boolean validateKualiStudent = true; 169 ServiceContractModel instance = new ServiceContractModelQDoxLoader(srcDirs, validateKualiStudent); 170 171 instance = new ServiceContractModelCache(instance); 172 validate(instance); 173 model2 = instance; 174 return instance; 175 } 176 177 private String dump(ServiceMethod method) { 178 StringBuilder bldr = new StringBuilder(); 179 bldr.append(method.getName()); 180 String comma = ""; 181 bldr.append("("); 182 for (ServiceMethodParameter param : method.getParameters()) { 183 bldr.append(comma); 184 comma = ", "; 185 bldr.append(param.getType()); 186 bldr.append(" "); 187 bldr.append(param.getName()); 188 } 189 bldr.append(")"); 190 return bldr.toString(); 191 } 192 193 private void validate(ServiceContractModel model) { 194 Collection<String> errors = 195 new ServiceContractModelValidator(model).validate(); 196 if (errors.size() > 0) { 197 StringBuilder buf = new StringBuilder(); 198 buf.append(errors.size()).append(" errors found while validating the data."); 199 int cnt = 0; 200 for (String msg : errors) { 201 cnt++; 202 buf.append("\n"); 203 buf.append("*error*").append(cnt).append(":").append(msg); 204 } 205 206 fail(buf.toString()); 207 } 208 } 209 private ModelFinder finder1 = null; 210 211 private ModelFinder getFinder1() { 212 if (finder1 == null) { 213 finder1 = new ModelFinder(getModel1()); 214 } 215 return finder1; 216 } 217 private ModelFinder finder2 = null; 218 219 private ModelFinder getFinder2() { 220 if (finder2 == null) { 221 finder2 = new ModelFinder(getModel2()); 222 } 223 return finder2; 224 } 225 226 private void compareTypes() { 227 for (Service service : model1.getServices()) { 228 log.info(""); 229 log.info("h2. " + service.getName() + " Structures"); 230 for (XmlType type : finder1.findAllComplexTypesInService(service.getKey())) { 231 findCompareType(type); 232 } 233 } 234 } 235 236 private String calcService(XmlType xmlType) { 237 StringBuilder bldr = new StringBuilder(); 238 String comma = ""; 239 for (String serviceKey : HtmlContractMessageStructureWriter.calcUsageByService(model1, xmlType)) { 240 bldr.append(comma); 241 comma = ", "; 242 bldr.append(serviceKey); 243 } 244 return bldr.toString(); 245 } 246 247 private String calcFieldNames(XmlType xmlType) { 248 StringBuilder bldr = new StringBuilder(); 249 String comma = ""; 250 for (MessageStructure ms : finder2.findMessageStructures(xmlType.getName())) { 251 bldr.append(comma); 252 comma = ", "; 253 bldr.append(ms.getShortName()); 254 } 255 return bldr.toString(); 256 } 257 private Map<String, String> knownUnconvertedObjects = null; 258 259 private void loadKnownUnconvertedObjects() { 260 Map<String, String> missings = new HashMap<String, String>(); 261 missings.put("ObjectStructureDefinition", "Old R1 dictionary not converted"); 262 missings.put("FieldDefinition", "Old R1 dictionary not converted"); 263 missings.put("ValidCharsConstraint", "Old R1 dictionary not converted"); 264 missings.put("RequiredConstraint", "Old R1 dictionary not converted"); 265 missings.put("CaseConstraint", "Old R1 dictionary not converted"); 266 missings.put("WhenConstraint", "Old R1 dictionary not converted"); 267 missings.put("Constraint", "Old R1 dictionary not converted"); 268 missings.put("MustOccurConstraint", "Old R1 dictionary not converted"); 269 missings.put("LookupConstraint", "Old R1 dictionary not converted"); 270 missings.put("CommonLookupParam", "Old R1 dictionary not converted"); 271 missings.put("CommonLookup", "Old R1 dictionary not converted"); 272 missings.put("DateRangeInfo", "DateRange was merged in with Milestone"); 273 missings.put("CredentialInfo", "LRC was revamped and Class II like objects were dropped"); 274 missings.put("CreditInfo", "LRC was revamped and Class II like objects were dropped"); 275 missings.put("ScaleInfo", "Changed to be ResultScaleInfo"); 276 missings.put("GradeInfo", "LRC was revamped and Class II like objects were dropped"); 277 missings.put("ResultComponentInfo", "Changed to be ResultValuesGroupInfo"); 278 missings.put("QueryParamInfo", "Is really a type object that holds typing info information about a parameter model as TypeInfo and use type-type relation to connnect it to search criteria"); 279 missings.put("FieldDescriptor", "Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 280 missings.put("SearchSelector", "Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 281 missings.put("ObjectStructure", "Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 282 missings.put("Type", "Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 283 missings.put("State", "Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 284 missings.put("Field", "Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 285 missings.put("ConstraintDescriptor", "Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 286 missings.put("ConstraintSelector", "Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 287 missings.put("RequireConstraint", "Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 288 missings.put("TypeStateCaseConstraint", "Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 289 missings.put("TypeStateWhenConstraint", "Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 290 missings.put("OccursConstraint", " Old pre-R1 dictionary structure that were attached to search param types were dropped -- ui dictionary provided that info"); 291 missings.put("ResultColumnInfo", " is really a type that describes the type of result that comes back, store as a TypeInfo object and use type-type relation to connect to result"); 292 // missings.put("SearchCriteriaTypeInfo", "The search criteria is really a type stucture that should be modeled as as TypeInfo and type-type relationship to connect it to a search type"); 293 missings.put("java.lang.String", ""); 294 missings.put("Map<String, String>", ""); 295 missings.put("LuiInfo", "Lui was pulled out and put in it's own service. The LuiInfo object was not used in R1 and was radically redesigned in R2"); 296 297 knownUnconvertedObjects = missings; 298 return; 299 } 300 private Map<String, String> knownObjectRenames = null; 301 302 private void loadKnownObjectRenames() { 303 Map<String, String> renames = new HashMap<String, String>(); 304 renames.put("Message", "MessageInfo"); 305 renames.put("SearchRequest", "SearchRequestInfo"); 306 renames.put("SearchResult", "SearchResultInfo"); 307 renames.put("SearchParam", "SearchParamInfo"); 308 renames.put("SearchResultRow", "SearchResultRowInfo"); 309 renames.put("SearchResultCell", "SearchResultCellInfo"); 310 renames.put("Message", "MessageInfo"); 311 knownObjectRenames = renames; 312 return; 313 } 314 private Map<String, String> knownFieldRenames = null; 315 316 private void loadKnownFieldRenames() { 317 Map<String, String> renames = new HashMap<String, String>(); 318 renames.put("id", "key"); // not all the time but when it happens want to catch if id not found 319 renames.put("desc", "descr"); 320 renames.put("state", "stateKey"); 321 renames.put("type", "typeKey"); 322 renames.put("metaInfo", "meta"); 323 renames.put("desc", "descr"); 324 renames.put("startTerm", "startTermId"); 325 renames.put("endTerm", "endTermId"); 326 renames.put("longDesc", "longDescr"); 327 renames.put("shortDesc", "shortDescr"); 328 renames.put("objectTypeURI", "refObjectUri"); 329 // TODO: this works but really should make these specific to the object they are connected with 330 renames.put("detailDesc", "descr"); 331 renames.put("milestoneDate", "startDate"); 332 renames.put("success", "isSuccess"); 333 renames.put("relationType", "relationTypeKey"); 334 renames.put("unitType", "unitTypeKey"); 335 renames.put("enrollable", "isEnrollable"); 336 renames.put("hazardousForDisabledStudents", "isHazardousForDisabledStudents"); 337 renames.put("versionInfo", "version"); 338 renames.put("primary", "isPrimary"); 339 renames.put("activityType", "typeKey"); 340 renames.put("loRepository", "loRepositoryKey"); 341 renames.put("queryParamValueList", "queryParamValues"); 342 renames.put("credentialProgramType", "typeKey"); 343 knownFieldRenames = renames; 344 return; 345 } 346 private Map<String, String> knownFieldIssues = null; 347 348 private void loadKnownFieldIssues() { 349 Map<String, String> issues = new HashMap<String, String>(); 350 issues.put("AtpInfo.key", "Switched from key to Id"); 351 issues.put("MilestoneInfo.key", "Switched from key to Id"); 352 issues.put("AtpInfo.id", ""); // suppress the extra field message from the r2 side 353 issues.put("MilestoneInfo.id", ""); // ditto 354 issues.put("MilestoneInfo.atpId", "Is not in R2 because a Milestone can be connected to more than one ATP so it is managed through a relationship"); 355 issues.put("Message.locale", "the type was changed from String to LocaleInfo to hold the different parts of the locale info"); 356 issues.put("SearchRequest.params", ""); 357 issues.put("SearchResult.rows", ""); 358 issues.put("SearchResultRow.cells", ""); 359 issues.put("ValidationResultInfo.errorLevel", ""); 360 issues.put("ValidationResultInfo.level", ""); 361 issues.put("ValidationResultInfo.ok", ""); 362 issues.put("ValidationResultInfo.warn", ""); 363 issues.put("ValidationResultInfo.error", ""); 364 issues.put("DocumentInfo.documentBinaryInfo", "renamd to just documentBinary (removing the trailing Info from the field name)"); 365 issues.put("OrgHierarchyInfo.key", "Switched from key to Id"); 366 issues.put("SearchResultTypeInfo.resultColumns", "ResultColumns is really anotther type to describe the column, Use type-type relation to hold that info"); 367 issues.put("ReqCompFieldTypeInfo.fieldDescriptor", "was dropped because it was an Old Pre-R1 dictionary and was not used -- UI dictionary provides that info instead"); 368 issues.put("LuTypeInfo.instructionalFormat", "Instructional format is a TypeInfo object and should be modeled as such using the type-type relation to connect it to a learning unit type"); 369 issues.put("LuTypeInfo.deliveryMethod", "Delivery method is a TypeInfo object and should be modeled as such using type-type relation to connect it to a learning unit type"); 370 issues.put("SearchCriteriaTypeInfo.queryParams", "Query Params is a TypeInfo that describes the parameter, model as type and type-type relation"); 371 issues.put("OrgOrgRelationTypeInfo.orgHierarchyKey", "This was removed because a particular relation type can participate in more than one hierarchies!"); 372 issues.put("SearchParam.value", "Renamed to values which is List<String>, in R1 the setValue method was overloaded to take a string or List, Kept in R2 but marked as deprecated"); 373 issues.put("", ""); 374 issues.put("", ""); 375 issues.put("", ""); 376 issues.put("", ""); 377 issues.put("", ""); 378 issues.put("", ""); 379 issues.put("", ""); 380 issues.put("", ""); 381 issues.put("", ""); 382 issues.put("", ""); 383 384 knownFieldIssues = issues; 385 return; 386 } 387 388 private XmlType findType(XmlType r1) { 389 XmlType r2 = finder2.findXmlType(r1.getName()); 390 if (r2 == null) { 391 String renamedName = this.knownObjectRenames.get(r1.getName()); 392 if (renamedName != null) { 393 r2 = finder2.findXmlType(renamedName); 394 if (r2 == null) { 395 log.info("# (-) " + r1.getName() + ": was not found even after being renamed to " + renamedName); 396 return null; 397 } 398 log.info("# (/) " + r1.getName() + ": was renamed to " + renamedName); 399 return r2; 400 } 401 } 402 if (r2 == null) { 403 if (r1.getName().endsWith("TypeInfo")) { 404 r2 = finder2.findXmlType("TypeInfo"); 405 } 406 } 407 return r2; 408 } 409 410 private void findCompareType(XmlType r1) { 411 if (r1.getName().endsWith("List")) { 412 return; 413 } 414 if (this.knownUnconvertedObjects.containsKey(r1.getName())) { 415 String message = this.knownUnconvertedObjects.get(r1.getName()); 416 if (message.isEmpty()) { 417 return; 418 } 419 log.info("# (/) " + r1.getName() + ":" + message); 420 return; 421 } 422 XmlType r2 = findType(r1); 423 if (r2 == null) { 424 log.info("# " + r1.getName() + ": has no corresponding object in r2"); 425 return; 426 } 427 Set<MessageStructure> usedInR2 = new HashSet<MessageStructure>(); 428 for (MessageStructure ms : finder1.findMessageStructures(r1.getName())) { 429 MessageStructure used = findCompareMessageStructure(ms, r2); 430 if (used != null) { 431 usedInR2.add(used); 432 } 433 } 434 // Don't report extra fields on type info 435 if (!r2.getName().equals("TypeInfo")) { 436 for (MessageStructure ms : finder2.findMessageStructures(r2.getName())) { 437 if (usedInR2.contains(ms)) { 438 continue; 439 } 440 String issue = this.knownFieldIssues.get(ms.getXmlObject() + "." + ms.getShortName()); 441 if (issue != null) { 442 if (!issue.isEmpty()) { 443 log.info("# (*g) " + ms.getXmlObject() + "." + ms.getShortName() + ": " + issue); 444 } 445 continue; 446 } 447 log.info("# (+) " + ms.getXmlObject() + "." + ms.getShortName() + " - new field added in R2"); 448 } 449 } 450 } 451 452 private MessageStructure findCompareMessageStructure(MessageStructure r1, XmlType xmlType2) { 453 MessageStructure r2 = findMessageStructure(r1, xmlType2); 454 String issue = this.knownFieldIssues.get(r1.getXmlObject() + "." + r1.getShortName()); 455 if (issue != null) { 456 if (!issue.isEmpty()) { 457 log.info("# (*g) " + r1.getXmlObject() + "." + r1.getShortName() + ": " + issue); 458 } 459 return r2; 460 } 461 if (r2 == null) { 462 if (xmlType2.getName().equals("TypeInfo")) { 463 if (r1.getShortName().endsWith("Type") 464 || r1.getShortName().endsWith("TypeInfo") 465 || r1.getShortName().endsWith("Types") 466 || r1.getShortName().endsWith("TypeInfos")) { 467 log.info("# (*g) " + r1.getXmlObject() + "." + r1.getShortName() + " was a type stored on a type: use type-type relationship instead"); 468 return null; 469 } 470 log.info("# (!) " + r1.getXmlObject() + "." + r1.getShortName() + " was extra data on type, store in dynamic attribute if actually used"); 471 return null; 472 } 473 log.info("# (-) " + r1.getXmlObject() + "." + r1.getShortName() + " not found in r2: renamed to one of these? " + calcFieldNames(xmlType2)); 474 return null; 475 } 476 compareType(r1, r2); 477 return r2; 478 } 479 480 private void compareType(MessageStructure r1, MessageStructure r2) { 481 if (r1.getType().equalsIgnoreCase(r2.getType())) { 482 return; 483 } 484 if (r1.getShortName().equals("attributes")) { 485 if (r1.getType().equals("Map<String, String>")) { 486 if (r2.getType().equals("AttributeInfoList")) { 487 return; 488 } 489 } 490 } 491 if (r1.getShortName().equals("desc") || r1.getShortName().equals("descr")) { 492 if (r1.getType().equals("String")) { 493 if (r2.getType().equals("RichTextInfo")) { 494 log.info("# (*g) " + r1.getXmlObject() + "." + r1.getShortName() + ": description type were changed to RichText, use plain version"); 495 return; 496 } 497 } 498 } 499 log.info("# (!) " + r1.getXmlObject() + "." + r1.getShortName() + ": the type was changed from " + r1.getType() + " to " + r2.getType()); 500 } 501 502 private MessageStructure findMessageStructure(MessageStructure r1, XmlType xmlType2) { 503 MessageStructure r2 = finder2.findMessageStructure(xmlType2.getName(), r1.getShortName()); 504 if (r2 == null) { 505 String renamed = this.knownFieldRenames.get(r1.getShortName()); 506 if (renamed != null) { 507 r2 = finder2.findMessageStructure(xmlType2.getName(), renamed); 508 if (r2 == null) { 509 log.info("# (-) " + r1.getXmlObject() + "." + r1.getShortName() 510 + " was renamed to " + xmlType2.getName() + "." + renamed 511 + " BUT IT STILL DIDN'T EXIST IN R2"); 512 return null; 513 } 514 log.info("# (*g) " + r1.getXmlObject() + "." + r1.getShortName() 515 + " was renamed to " + xmlType2.getName() + "." + renamed); 516 } 517 } 518 return r2; 519 } 520 521 private void compareMethods() { 522 for (Service service : model1.getServices()) { 523 log.info(""); 524 log.info("h2. " + service.getName() + " Methods"); 525 List<ServiceMethod> methodsInService = finder1.findServiceMethods(service.getKey()); 526 for (ServiceMethod method : methodsInService) { 527 findCompareMethod(method); 528 } 529 } 530 } 531 532 private void findCompareMethod(ServiceMethod method1) { 533 String issue = knownMethodIssues.get (method1.getService() + "Service." + method1.getName()); 534 if (issue != null) { 535 if (!issue.isEmpty()) { 536 log.info("# (*g) " + method1.getService() + "Service." + method1.getName() 537 + ": " + issue); 538 } 539 return; 540 } 541 ServiceMethod method2 = findMethod(method1); 542 if (method2 == null) { 543 // String possibleMethods = calcPossibleMethods(method1); 544 if (isTypeMethod(method1)) { 545 log.info("# (*g) " + method1.getService() + "Service." + method1.getName() 546 + " was dropped because it is a type, use TypeService instead"); 547 return; 548 } 549 String possibleMethods = this.calcPossibleMethods(method1); 550 if (possibleMethods.isEmpty()) { 551 log.info("# (-) " + method1.getService() + "Service." + method1.getName() 552 + " could not be found in R2"); 553 } else { 554 log.info("# (!) " + method1.getService() + "Service." + method1.getName() 555 + " might have been renamed to one of these: " 556 + possibleMethods); 557 } 558 return; 559 } 560 if (!method1.getName().equals(method2.getName())) { 561 log.info("# (*g) " + method1.getService() + "Service." + method1.getName() 562 + " was renamed to " + method2.getService() + "Service." + method2.getName()); 563 } 564 } 565 566 private ServiceMethod findMethod(ServiceMethod method1) { 567 ServiceMethod method2 = findMethod2(method1.getService(), method1.getName()); 568 if (method2 == null) { 569 String methodRename = knownMethodRenames.get(method1.getService() + "Service." + method1.getName()); 570 if (methodRename != null) { 571 method2 = findMethod2(method1.getService(), methodRename); 572 if (method2 == null) { 573 log.info("# (x) " + method1.getService() + "Service." + method1.getName() 574 + " could not be found even after being renamed to " + methodRename); 575 return null; 576 } 577 } 578 } 579 return method2; 580 } 581 private Map<String, String> knownMethodRenames = null; 582 583 private void loadKnownMethodRenames() { 584 Map<String, String> renames = new HashMap<String, String>(); 585 renames.put("AtpService.getAtpsByAtpType", "getAtpIdsByType"); 586 renames.put("AtpService.getMilestonesByAtp", "getMilestonesForAtp"); 587 renames.put("AtpService.addMilestone", "addMilestoneToAtp"); 588 renames.put("AtpService.removeMilestone", "removeMilestoneFromAtp"); 589 renames.put("MessageService.getMessageGroups", "getMessageGroupKeys"); 590 renames.put("CommentService.getComments", "getCommentsByReferenceAndType"); 591 renames.put("CommentService.getTags", "getTagsByReferenceAndType"); 592 renames.put("CommentService.addTag", "createTag"); 593 renames.put("CommentService.addComment", "createComment"); 594 renames.put("CommentService.removeComment", "deleteComment"); 595 renames.put("CommentService.removeTag", "deleteTag"); 596 renames.put("CommentService.removeComments", "deleteCommentsByReference"); 597 renames.put("CommentService.removeTags", "deleteTagsByReference"); 598 renames.put("DocumentService.getDocumentsByIdList", "getDocumentsByIds"); 599 renames.put("DocumentService.getCategoriesByDocument", "getDocumentCategoriesByDocumentId"); 600 renames.put("DocumentService.getRefDocRelationsByDoc", "getRefDocRelationsByDocument"); 601 renames.put("EnumerationManagementService.removeEnumeratedValue", "deleteEnumeratedValue"); 602 renames.put("OrganizationService.getOrganization", "getOrg"); 603 renames.put("OrganizationService.getOrganizationsByIdList", "getOrgsByIds"); 604 renames.put("OrganizationService.getOrgOrgRelationsByIdList", "getOrgOrgRelationsByIds"); 605 renames.put("OrganizationService.getOrgPersonRelationsByIdList", "getOrgPersonRelationsByIds"); 606 renames.put("OrganizationService.getPersonIdsForOrgByRelationType", ""); 607 renames.put("OrganizationService.getAllOrgPersonRelationsByPerson", "getOrgPersonRelationsByPerson"); 608 renames.put("OrganizationService.getAllOrgPersonRelationsByOrg", "getOrgPersonRelationsByOrg"); 609 renames.put("OrganizationService.createOrganization", "createOrg"); 610 renames.put("OrganizationService.updateOrganization", "updateOrg"); 611 renames.put("OrganizationService.deleteOrganization", "deleteOrg"); 612 renames.put("OrganizationService.validateOrganization", "validateOrg"); 613 renames.put("OrganizationService.removeOrgOrgRelation", "deleteOrgOrgRelation"); 614 renames.put("OrganizationService.removeOrgPersonRelation", "deleteOrgPersonRelation"); 615 renames.put("OrganizationService.addPositionRestrictionToOrg", "createOrgPositionRestriction"); 616 renames.put("OrganizationService.updatePositionRestrictionForOrg", "updateOrgPositionRestriction"); 617 renames.put("OrganizationService.removePositionRestrictionFromOrg", "deleteOrgPositionRestriction"); 618 renames.put("StatementService.getStatementsUsingReqComponent", "getStatementsByReqComponent"); 619 renames.put("StatementService.getStatementsUsingStatement", "getStatementsForStatement"); 620 renames.put("CourseService.getCourseFormats", "getCourseFormatsByCourse"); 621 renames.put("CourseService.getCourseActivities", "getCourseActivitiesByCourseFormat"); 622 renames.put("CourseService.getCourseLos", "getCourseLearningObjectivesByCourse"); 623 renames.put("LearningObjectiveService.getLoCategories", "getLoCategoriesByLoRepository"); 624 renames.put("LearningObjectiveService.getLoByIdList", "getLosByIds"); 625 renames.put("LearningObjectiveService.getLosByRepository", "getLosByLoRepository"); 626 renames.put("LearningObjectiveService.getLoCategoriesForLo", "getLoCategoriesByLo"); 627 renames.put("LrcService.getResultComponent", "getResultValuesGroup"); 628 renames.put("LuService.getClusByIdList", "getClusByIds"); 629 renames.put("LuService.getAllowedLuLuRelationTypesByCluId", "getAllowedCluCluRelationTypesByClu"); 630 renames.put("LuService.getClusByRelation", "getClusByRelatedCluAndRelationType"); 631 renames.put("LuService.getCluIdsByRelation", "getCluIdsByRelatedCluAndRelationType"); 632 renames.put("LuService.getRelatedClusByCluId", "getRelatedClusByCluAndRelationType"); 633 renames.put("LuService.getRelatedCluIdsByCluId", "getRelatedCluIdsByCluAndRelationType"); 634 renames.put("LuService.getCluPublicationsByCluId", "getCluPublicationsByClu"); 635 renames.put("LuService.getResourceRequirementsForCluId", "getResourceRequirementsForClu"); 636 renames.put("LuService.getCluSetInfo", "getCluSet"); 637 renames.put("LuService.getCluSetInfoByIdList", "getCluSetsByIds"); 638 renames.put("LuService.getLuisByIdList", "getLuisByIds"); 639 renames.put("ProgramService.getMajorIdsByCredentialProgramType", "getMajorDisciplineIdsByCredentialProgramType"); 640 renames.put("ProgramService.getVariationsByMajorDisciplineId", "getProgramVariationsByMajorDiscipline"); 641 renames.put("ProgramService.getHonorsByCredentialProgramType", "getHonorProgramIdsByCredentialProgramType"); 642 renames.put("ProposalService.getProposalsByIdList", "getProposalsByIds"); 643 renames.put("", ""); 644 renames.put("", ""); 645 knownMethodRenames = renames; 646 return; 647 } 648 649 private Map<String, String> knownMethodIssues = null; 650 651 private void loadKnownMethodIssues() { 652 Map<String, String> issues = new HashMap<String, String>(); 653 issues.put("AtpService.validateDateRange", "Dropped because DateRange objects were merged in with milestones"); 654 issues.put("AtpService.getDateRange", "Dropped because DateRange objects were merged in with milestones"); 655 issues.put("AtpService.getDateRangesByAtp", "Dropped because DateRange objects were merged in with milestones"); 656 issues.put("AtpService.getDateRangesByDate", "Dropped because DateRange objects were merged in with milestones"); 657 issues.put("AtpService.addDateRange", "Dropped because DateRange objects were merged in with milestones"); 658 issues.put("AtpService.updateDateRange", "Dropped because DateRange objects were merged in with milestones"); 659 issues.put("AtpService.removeDateRange", "Dropped because DateRange objects were merged in with milestones"); 660 issues.put("DictionaryService.getObjectTypes", "Dictionary service was completely revamped to match KRAD, old one is still around use that for R1 stuff"); 661 issues.put("DictionaryService.getObjectStructure", "Dictionary service was completely revamped to match KRAD, old one is still around use that for R1 stuff"); 662 issues.put("CommentService.getCommentsByType", "Renamed and changed to just get Ids, so use getCommentIdsByType then call getCommentsByIds"); 663 issues.put("CommentService.getTagsByType", "Renamed and changed to just get Ids, so use getTagIdsByType then call getTagsByIds"); 664 issues.put("DocumentService.getRefObjectTypes", "(!) has been dropped from the contract, the document service should store any uri"); 665 issues.put("DocumentService.getRefObjectSubTypes", "(!) has been dropped from the contract, the document service should store any uri and sub-object URI"); 666 issues.put("OrganizationService.getOrgOrgRelationsByRelatedOrg", " (!) the two methods for tranversing by one side of the relationship or other has replaced by a single method that finds relationships no matter which side it is on (?) Need to possibly rethink this it imposes a big change on both the implementation and on the the application. "); 667 issues.put("OrganizationService.getPersonIdsForOrgByRelationType", "Was removed, instead use getOrgPersonRelationsByTypeAndPerson and loop through the relationships to get the list of personIds that you want. The issue was the old method did not take into account relationships that are old/inactive so using it would lead to errors that would only appear once transitions occured in the people being related to the org."); 668 issues.put("OrganizationService.getOrgPersonRelationsByPerson", "Renamd to getOrgPersonRelationsByOrgAndPerson, because the R1 was badly named, it said just by person but the parameters required an Org as well!"); 669 issues.put("OrganizationService.getPositionRestrictionsByOrg", "use getOrgPositionRestrictionIdsByOrg then call getOrgPositionRestrictionsByIds to get the objects"); 670 issues.put("LearningObjectiveService.getAllowedLoLoRelationTypesForLoType", "is a type method, use Type Service instead"); 671 issues.put("LrcService.getCredential", "Is a Class 2 concept and as dropped from the Class 1 service"); 672 issues.put("LrcService.getCredentialsByKeyList", "Is a Class 2 concept and as dropped from the Class 1 service"); 673 issues.put("LrcService.getCredentialKeysByCredentialType", "Is a Class 2 concept and as dropped from the Class 1 service"); 674 issues.put("LrcService.getCredit", "Is a Class 2 concept and as dropped from the Class 1 service"); 675 issues.put("LrcService.getCreditsByKeyList", "Is a Class 2 concept and as dropped from the Class 1 service"); 676 issues.put("LrcService.getCreditKeysByCreditType", "Is a Class 2 concept and as dropped from the Class 1 service"); 677 issues.put("LrcService.getGrade", "Is a Class 2 concept and as dropped from the Class 1 service"); 678 issues.put("LrcService.getGradesByKeyList", "Is a Class 2 concept and as dropped from the Class 1 service"); 679 issues.put("LrcService.getGradeKeysByGradeType", "Is a Class 2 concept and as dropped from the Class 1 service"); 680 issues.put("LrcService.getGradesByScale", "Is a Class 2 concept and as dropped from the Class 1 service"); 681 issues.put("LrcService.translateGrade", "(-) is not being supported at this time, translations will be added later"); 682 issues.put("LrcService.compareGrades", "(-) is not being supported at this time, comparisons will be added later"); 683 issues.put("LrcService.getResultComponentIdsByResultComponentType", "roughly maps to getResultValuesGroupIdsByType but they are different objects and the types have changed as well"); 684 issues.put("LrcService.getResultComponentIdsByResult", "roughly maps to getResultValuesGroupsByResultValue but doesn't take the extra type parameter"); 685 issues.put("LrcService.createResultComponent", "rougly maps to createResultValuesGroup"); 686 issues.put("LrcService.updateResultComponent", "rougly maps to updateResultValuesGroup"); 687 issues.put("LrcService.deleteResultComponent", "rougly maps to deleteResultValuesGroup"); 688 issues.put("LrcService.getScale", "roughly maps to getResultScale"); 689 issues.put("LuService.getAllowedLuLuRelationTypesByLuiId", "is a type method, use TypeService instead"); 690 issues.put("", ""); 691 issues.put("", ""); 692 issues.put("", ""); 693 issues.put("", ""); 694 knownMethodIssues = issues; 695 return; 696 } 697 698 699 private ServiceMethod findMethod2(String serviceKey, String methodName) { 700 ServiceMethod method2 = finder2.findServiceMethod(serviceKey, methodName); 701 if (method2 == null) { 702 if (serviceKey.equals("Lu")) { 703 method2 = finder2.findServiceMethod("Clu", methodName); 704 if (method2 == null) { 705 method2 = finder2.findServiceMethod("Lui", methodName); 706 } 707 } 708 } 709 return method2; 710 } 711 712 private String calcMethods(ServiceMethod method1) { 713 StringBuilder bldr = new StringBuilder(); 714 String comma = ""; 715 for (ServiceMethod method2 : finder2.findServiceMethods(method1.getService())) { 716 bldr.append(comma); 717 comma = ", "; 718 bldr.append(method2.getName()); 719 } 720 return bldr.toString(); 721 } 722 723 private String calcPossibleMethods(ServiceMethod method1) { 724 StringBuilder bldr = new StringBuilder(); 725 String comma = ""; 726 for (ServiceMethod method2 : findPossibleMethods(method1)) { 727 bldr.append(comma); 728 comma = ", "; 729 bldr.append(method2.getName()); 730 } 731 return bldr.toString(); 732 } 733 734 private List<ServiceMethod> findPossibleMethods(ServiceMethod method1) { 735 List<ServiceMethod> methods = new ArrayList<ServiceMethod>(); 736 List<ServiceMethod> wideNet = null; 737 if (method1.getService().equals("Lu")) { 738 wideNet = finder2.findServiceMethods("Clu"); 739 wideNet.addAll(finder2.findServiceMethods("Lui")); 740 } else { 741 wideNet = finder2.findServiceMethods(method1.getService()); 742 } 743 for (ServiceMethod method2 : wideNet) { 744 if (isPossibleMatch(method1, method2)) { 745 methods.add(method2); 746 } 747 } 748 return methods; 749 } 750 751 private boolean isPossibleMatch(ServiceMethod method1, ServiceMethod method2) { 752 if (method1.getName().contains(method2.getName())) { 753 return true; 754 } 755 if (method2.getName().contains(method1.getName())) { 756 return true; 757 } 758 if (method1.getName().startsWith("get") && method2.getName().startsWith("get")) { 759 return true; 760 } 761 if (method1.getName().startsWith("add") && method2.getName().startsWith("create")) { 762 return true; 763 } 764 if (method1.getName().startsWith("create") && method2.getName().startsWith("create")) { 765 return true; 766 } 767 if (method1.getName().startsWith("update") && method2.getName().startsWith("update")) { 768 return true; 769 } 770 if (method1.getName().startsWith("delete") && method2.getName().startsWith("delete")) { 771 return true; 772 } 773 if (method1.getName().startsWith("remove") && method2.getName().startsWith("delete")) { 774 return true; 775 } 776 if (method1.getName().startsWith("validate") && method2.getName().startsWith("validate")) { 777 return true; 778 } 779 return false; 780 } 781 782 private boolean isTypeMethod(ServiceMethod method1) { 783 if (method1.getReturnValue().getType().endsWith("TypeInfo")) { 784 return true; 785 } 786 if (method1.getReturnValue().getType().endsWith("TypeInfoList")) { 787 return true; 788 } 789 return false; 790 } 791 }