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("", ""); 620 renames.put("", ""); 621 renames.put("", ""); 622 renames.put("", ""); 623 renames.put("", ""); 624 knownMethodRenames = renames; 625 return; 626 } 627 628 private Map<String, String> knownMethodIssues = null; 629 630 private void loadKnownMethodIssues() { 631 Map<String, String> issues = new HashMap<String, String>(); 632 issues.put("AtpService.validateDateRange", "Dropped because DateRange objects were merged in with milestones"); 633 issues.put("AtpService.getDateRange", "Dropped because DateRange objects were merged in with milestones"); 634 issues.put("AtpService.getDateRangesByAtp", "Dropped because DateRange objects were merged in with milestones"); 635 issues.put("AtpService.getDateRangesByDate", "Dropped because DateRange objects were merged in with milestones"); 636 issues.put("AtpService.addDateRange", "Dropped because DateRange objects were merged in with milestones"); 637 issues.put("AtpService.updateDateRange", "Dropped because DateRange objects were merged in with milestones"); 638 issues.put("AtpService.removeDateRange", "Dropped because DateRange objects were merged in with milestones"); 639 issues.put("DictionaryService.getObjectTypes", "Dictionary service was completely revamped to match KRAD, old one is still around use that for R1 stuff"); 640 issues.put("DictionaryService.getObjectStructure", "Dictionary service was completely revamped to match KRAD, old one is still around use that for R1 stuff"); 641 issues.put("CommentService.getCommentsByType", "Renamed and changed to just get Ids, so use getCommentIdsByType then call getCommentsByIds"); 642 issues.put("CommentService.getTagsByType", "Renamed and changed to just get Ids, so use getTagIdsByType then call getTagsByIds"); 643 issues.put("DocumentService.getRefObjectTypes", "Use type service but (!) there is no getRefObjectUris () method"); 644 issues.put("DocumentService.getRefObjectSubTypes", "Use type service but (!) but do not have a refObject 'subtype' defined"); 645 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. "); 646 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."); 647 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!"); 648 issues.put("OrganizationService.getPositionRestrictionsByOrg", "use getOrgPositionRestrictionIdsByOrg then call getOrgPositionRestrictionsByIds to get the objects"); 649 issues.put("LearningObjectiveService.getAllowedLoLoRelationTypesForLoType", "is a type method, use Type Service instead"); 650 issues.put("LrcService.getCredential", "Is a Class 2 concept and as dropped from the Class 1 service"); 651 issues.put("LrcService.getCredentialsByKeyList", "Is a Class 2 concept and as dropped from the Class 1 service"); 652 issues.put("LrcService.getCredentialKeysByCredentialType", "Is a Class 2 concept and as dropped from the Class 1 service"); 653 issues.put("LrcService.getCredit", "Is a Class 2 concept and as dropped from the Class 1 service"); 654 issues.put("LrcService.getCreditsByKeyList", "Is a Class 2 concept and as dropped from the Class 1 service"); 655 issues.put("LrcService.getCreditKeysByCreditType", "Is a Class 2 concept and as dropped from the Class 1 service"); 656 issues.put("LrcService.getGrade", "Is a Class 2 concept and as dropped from the Class 1 service"); 657 issues.put("LrcService.getGradesByKeyList", "Is a Class 2 concept and as dropped from the Class 1 service"); 658 issues.put("LrcService.getGradeKeysByGradeType", "Is a Class 2 concept and as dropped from the Class 1 service"); 659 issues.put("LrcService.getGradesByScale", "Is a Class 2 concept and as dropped from the Class 1 service"); 660 issues.put("LrcService.translateGrade", "(-) is not being supported at this time, translations will be added later"); 661 issues.put("LrcService.compareGrades", "(-) is not being supported at this time, comparisons will be added later"); 662 issues.put("LrcService.getResultComponentIdsByResultComponentType", "roughly maps to getResultValuesGroupIdsByType but they are different objects and the types have changed as well"); 663 issues.put("LrcService.getResultComponentIdsByResult", "roughly maps to getResultValuesGroupsByResultValue but doesn't take the extra type parameter"); 664 issues.put("LrcService.createResultComponent", "rougly maps to createResultValuesGroup"); 665 issues.put("LrcService.updateResultComponent", "rougly maps to updateResultValuesGroup"); 666 issues.put("LrcService.deleteResultComponent", "rougly maps to deleteResultValuesGroup"); 667 issues.put("LrcService.getScale", "roughly maps to getResultScale"); 668 issues.put("", ""); 669 issues.put("", ""); 670 issues.put("", ""); 671 issues.put("", ""); 672 knownMethodIssues = issues; 673 return; 674 } 675 676 677 private ServiceMethod findMethod2(String serviceKey, String methodName) { 678 ServiceMethod method2 = finder2.findServiceMethod(serviceKey, methodName); 679 if (method2 == null) { 680 if (serviceKey.equals("Lu")) { 681 method2 = finder2.findServiceMethod("Clu", methodName); 682 if (method2 == null) { 683 method2 = finder2.findServiceMethod("Lui", methodName); 684 } 685 } 686 } 687 return method2; 688 } 689 690 private String calcMethods(ServiceMethod method1) { 691 StringBuilder bldr = new StringBuilder(); 692 String comma = ""; 693 for (ServiceMethod method2 : finder2.findServiceMethods(method1.getService())) { 694 bldr.append(comma); 695 comma = ", "; 696 bldr.append(method2.getName()); 697 } 698 return bldr.toString(); 699 } 700 701 private String calcPossibleMethods(ServiceMethod method1) { 702 StringBuilder bldr = new StringBuilder(); 703 String comma = ""; 704 for (ServiceMethod method2 : findPossibleMethods(method1)) { 705 bldr.append(comma); 706 comma = ", "; 707 bldr.append(method2.getName()); 708 } 709 return bldr.toString(); 710 } 711 712 private List<ServiceMethod> findPossibleMethods(ServiceMethod method1) { 713 List<ServiceMethod> methods = new ArrayList<ServiceMethod>(); 714 List<ServiceMethod> wideNet = null; 715 if (method1.getService().equals("Lu")) { 716 wideNet = finder2.findServiceMethods("Clu"); 717 wideNet.addAll(finder2.findServiceMethods("Lui")); 718 } else { 719 wideNet = finder2.findServiceMethods(method1.getService()); 720 } 721 for (ServiceMethod method2 : wideNet) { 722 if (isPossibleMatch(method1, method2)) { 723 methods.add(method2); 724 } 725 } 726 return methods; 727 } 728 729 private boolean isPossibleMatch(ServiceMethod method1, ServiceMethod method2) { 730 if (method1.getName().contains(method2.getName())) { 731 return true; 732 } 733 if (method2.getName().contains(method1.getName())) { 734 return true; 735 } 736 if (method1.getName().startsWith("get") && method2.getName().startsWith("get")) { 737 return true; 738 } 739 if (method1.getName().startsWith("add") && method2.getName().startsWith("create")) { 740 return true; 741 } 742 if (method1.getName().startsWith("create") && method2.getName().startsWith("create")) { 743 return true; 744 } 745 if (method1.getName().startsWith("update") && method2.getName().startsWith("update")) { 746 return true; 747 } 748 if (method1.getName().startsWith("delete") && method2.getName().startsWith("delete")) { 749 return true; 750 } 751 if (method1.getName().startsWith("remove") && method2.getName().startsWith("delete")) { 752 return true; 753 } 754 if (method1.getName().startsWith("validate") && method2.getName().startsWith("validate")) { 755 return true; 756 } 757 return false; 758 } 759 760 private boolean isTypeMethod(ServiceMethod method1) { 761 if (method1.getReturnValue().getType().endsWith("TypeInfo")) { 762 return true; 763 } 764 if (method1.getReturnValue().getType().endsWith("TypeInfoList")) { 765 return true; 766 } 767 return false; 768 } 769 }