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