001 /** 002 * Copyright 2005-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.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.krms.test; 017 018 import org.joda.time.DateTime; 019 import org.junit.Before; 020 import org.junit.Test; 021 import org.kuali.rice.core.api.lifecycle.Lifecycle; 022 import org.kuali.rice.kew.util.PerformanceLogger; 023 import org.kuali.rice.krms.api.KrmsApiServiceLocator; 024 import org.kuali.rice.krms.api.engine.EngineResults; 025 import org.kuali.rice.krms.api.engine.ExecutionFlag; 026 import org.kuali.rice.krms.api.engine.ExecutionOptions; 027 import org.kuali.rice.krms.api.engine.Facts; 028 import org.kuali.rice.krms.api.engine.ResultEvent; 029 import org.kuali.rice.krms.api.engine.SelectionCriteria; 030 import org.kuali.rice.krms.api.repository.LogicalOperator; 031 import org.kuali.rice.krms.api.repository.action.ActionDefinition; 032 import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition; 033 import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition; 034 import org.kuali.rice.krms.api.repository.context.ContextDefinition; 035 import org.kuali.rice.krms.api.repository.function.FunctionDefinition; 036 import org.kuali.rice.krms.api.repository.function.FunctionParameterDefinition; 037 import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition; 038 import org.kuali.rice.krms.api.repository.proposition.PropositionParameter; 039 import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType; 040 import org.kuali.rice.krms.api.repository.proposition.PropositionType; 041 import org.kuali.rice.krms.api.repository.rule.RuleDefinition; 042 import org.kuali.rice.krms.api.repository.term.TermDefinition; 043 import org.kuali.rice.krms.api.repository.term.TermParameterDefinition; 044 import org.kuali.rice.krms.api.repository.term.TermResolverDefinition; 045 import org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition; 046 import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition; 047 import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition; 048 import org.kuali.rice.krms.impl.repository.ActionBoService; 049 import org.kuali.rice.krms.impl.repository.AgendaBoService; 050 import org.kuali.rice.krms.impl.repository.FunctionBoServiceImpl; 051 import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator; 052 import org.kuali.rice.krms.impl.repository.RuleBoService; 053 import org.kuali.rice.krms.impl.repository.TermBo; 054 import org.kuali.rice.krms.impl.repository.TermBoService; 055 import org.kuali.rice.krms.impl.repository.TermSpecificationBo; 056 import org.kuali.rice.test.BaselineTestCase.BaselineMode; 057 import org.kuali.rice.test.BaselineTestCase.Mode; 058 import org.kuali.rice.test.ClearDatabaseLifecycle; 059 import org.springframework.transaction.annotation.Transactional; 060 061 import java.util.ArrayList; 062 import java.util.Collections; 063 import java.util.HashMap; 064 import java.util.List; 065 import java.util.Map; 066 067 import static org.junit.Assert.*; 068 069 @BaselineMode(Mode.CLEAR_DB) 070 public class KSLumKRMSDataSetupTest extends KSLumAbstractBoTest { 071 072 public static final String CAMPUS_CODE_TERM_NAME = "campusCodeTermSpec"; 073 074 static final String NAMESPACE1 = "KRMS_TEST_1"; 075 static final String NAMESPACE2 = "KRMS_TEST_2"; 076 static final String KSNAMESPACE = "KR-RULE-TEST"; 077 static final String TSUNAMI_EVENT = "Tsunami"; 078 static final String EARTHQUAKE_EVENT = "Earthquake"; 079 static final String KSContextRepeatableforCredit = "Repeatable for Credit"; 080 static final String CONTEXT2 = "Context2"; 081 static final String NAME = "name"; 082 static final String CONTEXT1_QUALIFIER = "KSLum Qualifer 1"; 083 static final String CONTEXT1_QUALIFIER_VALUE = "KSLum Qualifer 1 - Value"; 084 static final String CONTEXT2_QUALIFIER = "KSLum Qualifer 1"; 085 static final String CONTEXT2_QUALIFIER_VALUE = "KSLum Qualifer 2 - Value"; 086 static final String AGENDA1 = "TestAgenda1"; 087 static final String AGENDA2 = "Agenda2"; 088 static final String AGENDA3 = "Agenda3"; 089 static final String AGENDA4 = "Agenda4"; 090 static final String AGENDA_MayBeRepeatedForAMaxOfnCredits = "May be repeated for a maximum of <n> credits"; 091 static final String AGENDA_MustNotHaveSuccessfullyCompletedCourse = "Must not have successfully completed <course>"; 092 static final String AGENDA_MustHaveSuccessfullyCompletedAMinOfnCreditsFromCoursesInTheOrg = "Must have successfully completed a minimum of <n> credits from courses in the <org>"; 093 094 static final String PREREQ_TERM_NAME = "prereqTermSpec"; 095 static final String PREREQ_TERM_VALUE = "prereqValue"; 096 static final String NAMESPACE_CODE = "namespaceCode"; 097 static final String BOOL1 = "bool1"; 098 static final String BOOL2 = "bool2"; 099 100 // // Services needed for creation: 101 private TermBoService termBoService; 102 103 private RuleBoService ruleBoService; 104 private AgendaBoService agendaBoService; 105 private ActionBoService actionBoService; 106 private FunctionBoServiceImpl functionBoService; 107 108 private static final String ATTR_NUMBER_OF_CREDITS = "Number of Credits"; 109 private static final String ATTR_DEPT_ORG_NUMBER = "Dept Org Number"; 110 private static final String ATTR_PROPOSED_COURSE = "Proposed Course"; 111 private static final String ATTR_APPROVED_COURSE = "Approved Course"; 112 113 private static final String TERM_SPEC_CREDITS = "Credits"; 114 private static final String TERM_SPEC_ORG_NUMBER = "Org Number"; 115 private static final String TERM_SPEC_COURSE = "Course"; 116 private static final String TERM_SPEC_COURSE_NUMBER = "Course Number"; 117 private static final String TERM_SPEC_DATE = "Date"; 118 private static final String TERM_SPEC_GPA = "GPA"; 119 private static final String TERM_SPEC_GRADE = "Grade"; 120 private static final String TERM_SPEC_GRADE_TYPE = "GradeType"; 121 private static final String TERM_SPEC_LEARNING_OBJECTIVES = "Learning Objectives"; 122 123 /** 124 * 125 * Setting it up so that KRMS tables are not reset between test methods to 126 * make it run much faster 127 * 128 * @return 129 */ 130 protected List<String> getPerTestTablesNotToClear() { 131 List<String> tablesNotToClear = super.getPerTestTablesNotToClear(); 132 133 tablesNotToClear.add("KRMS_.*"); 134 135 return tablesNotToClear; 136 } 137 138 @Before 139 public void setup() { 140 // Reset TestActionTypeService 141 TestActionTypeService.resetActionsFired(); 142 143 termBoService = KrmsRepositoryServiceLocator.getTermBoService(); 144 contextRepository = KrmsRepositoryServiceLocator.getContextBoService(); 145 krmsTypeRepository = KrmsRepositoryServiceLocator 146 .getKrmsTypeRepositoryService(); 147 148 ruleBoService = KrmsRepositoryServiceLocator.getRuleBoService(); 149 agendaBoService = KrmsRepositoryServiceLocator.getAgendaBoService(); 150 actionBoService = KrmsRepositoryServiceLocator 151 .getBean("actionBoService"); 152 functionBoService = KrmsRepositoryServiceLocator 153 .getBean("functionRepositoryService"); 154 krmsAttributeDefinitionService = KrmsRepositoryServiceLocator 155 .getKrmsAttributeDefinitionService(); 156 157 boolean doTermDefinitions = true; 158 if (doTermDefinitions ) { 159 // createAllLumTermDefinitions(KSNAMESPACE); 160 } else { 161 162 ContextDefinition contextRecommendedPreparation = contextRepository 163 .getContextByNameAndNamespace(KSContextRepeatableforCredit, 164 KSNAMESPACE); 165 ContextDefinition contextRepeatableForCredit = contextRepository 166 .getContextByNameAndNamespace(KSContextRepeatableforCredit, 167 KSNAMESPACE); 168 169 // only set this stuff up if we don't already have Context1 (we 170 // don't clear out KRMS tables between test methods) 171 if (contextRecommendedPreparation == null) { 172 173 PerformanceLogger perfLog = new PerformanceLogger(); 174 perfLog.log("starting agenda creation"); 175 176 createAllLumAttributeDefinitions(KSNAMESPACE); 177 createAllLumTermDefinitions(KSNAMESPACE); 178 KrmsTypeDefinition krmsContextTypeDefinition = createContextType(KSNAMESPACE); 179 180 contextRepeatableForCredit = createContext(KSNAMESPACE, 181 "Repeatable for Credit", krmsContextTypeDefinition); 182 183 contextRecommendedPreparation = createContext(KSNAMESPACE, 184 "Recommended Preparation", krmsContextTypeDefinition); 185 186 // Term Specifications 187 188 // Term Definitions 189 createAllLumTermDefinitions(KSNAMESPACE); 190 191 // createRulesForAgenda(agendaName, contextDefinition, 192 // eventName, 193 // nameSpace, agendaDef); 194 195 // contextDefintion1 = createContextDefinition(KSNAMESPACE, 196 // KSContextRepeatableforCredit, Collections.singletonMap( 197 // CONTEXT1_QUALIFIER, CONTEXT1_QUALIFIER_VALUE)); 198 199 // createAgendaDefinition(AGENDA1, contextDefintion1, 200 // TSUNAMI_EVENT, KSNAMESPACE); 201 202 // ContextDefinition contextDefinition2 = 203 // createContextDefinition(NAMESPACE2, CONTEXT2, 204 // Collections.singletonMap( 205 // CONTEXT2_QUALIFIER, CONTEXT2_QUALIFIER_VALUE)); 206 // 207 // // Create multiple agendas so that we can test selection 208 // createAgendaDefinition(AGENDA2, contextDefinition2, 209 // EARTHQUAKE_EVENT, NAMESPACE2); 210 // createAgendaDefinition(AGENDA3, contextDefinition2, 211 // EARTHQUAKE_EVENT, NAMESPACE2); 212 // createAgendaDefinition(AGENDA4, contextDefinition2, 213 // TSUNAMI_EVENT, NAMESPACE2); 214 215 perfLog.log("finished agenda creation", true); 216 } 217 218 // KrmsTypeDefinition krmsGenericTypeDefinition = 219 // createKrmsGenericTypeDefinition(KSNAMESPACE, 220 // "testAgendaTypeService", "event name", "Event"); 221 // 222 // createAgendaDefinition(AGENDA_MayBeRepeatedForAMaxOfnCredits, 223 // contextRepeatableForCredit, TSUNAMI_EVENT, KSNAMESPACE, 224 // krmsGenericTypeDefinition); 225 // createAgendaDefinition(AGENDA_MustNotHaveSuccessfullyCompletedCourse, 226 // contextRecommendedPreparation, TSUNAMI_EVENT, KSNAMESPACE, 227 // krmsGenericTypeDefinition); 228 // createAgendaDefinition(AGENDA_MustHaveSuccessfullyCompletedAMinOfnCreditsFromCoursesInTheOrg, 229 // contextRecommendedPreparation, TSUNAMI_EVENT, KSNAMESPACE, 230 // krmsGenericTypeDefinition); 231 } 232 } 233 234 private void createTerms() { 235 236 } 237 238 @Test 239 public void testNothing() { 240 System.out.println("Tested setup"); 241 } 242 243 @Transactional 244 // @Test 245 public void testSelectAgendaByAttributeAndName() { 246 247 Map<String, String> contextQualifiers = new HashMap<String, String>(); 248 contextQualifiers.put(NAMESPACE_CODE, NAMESPACE1); 249 contextQualifiers.put(NAME, KSContextRepeatableforCredit); 250 contextQualifiers.put(CONTEXT1_QUALIFIER, CONTEXT1_QUALIFIER_VALUE); 251 252 Map<String, String> agendaQualifiers = new HashMap<String, String>(); 253 agendaQualifiers.put(AgendaDefinition.Constants.EVENT, TSUNAMI_EVENT); 254 agendaQualifiers.put(NAME, AGENDA1); 255 256 DateTime now = new DateTime(); 257 258 SelectionCriteria sc1 = SelectionCriteria.createCriteria(now, 259 contextQualifiers, Collections.singletonMap( 260 AgendaDefinition.Constants.EVENT, TSUNAMI_EVENT)); 261 262 Facts.Builder factsBuilder1 = Facts.Builder.create(); 263 factsBuilder1.addFact(CAMPUS_CODE_TERM_NAME, "BL"); 264 factsBuilder1.addFact(BOOL1, "true"); 265 factsBuilder1.addFact(BOOL2, Boolean.TRUE); 266 factsBuilder1.addFact(PREREQ_TERM_NAME, PREREQ_TERM_VALUE); 267 268 ExecutionOptions xOptions1 = new ExecutionOptions(); 269 xOptions1.setFlag(ExecutionFlag.LOG_EXECUTION, true); 270 271 PerformanceLogger perfLog = new PerformanceLogger(); 272 perfLog.log("starting rule execution"); 273 EngineResults eResults1 = KrmsApiServiceLocator.getEngine().execute( 274 sc1, factsBuilder1.build(), xOptions1); 275 perfLog.log("finished rule execution", true); 276 List<ResultEvent> rEvents1 = eResults1.getAllResults(); 277 278 List<ResultEvent> ruleEvaluationResults1 = eResults1 279 .getResultsOfType(ResultEvent.RULE_EVALUATED.toString()); 280 281 assertEquals("4 rules should have been evaluated", 4, 282 ruleEvaluationResults1.size()); 283 284 assertTrue("rule 0 should have evaluated to true", 285 ruleEvaluationResults1.get(0).getResult()); 286 assertFalse("rule 1 should have evaluated to false", 287 ruleEvaluationResults1.get(1).getResult()); 288 assertTrue("rule 2 should have evaluated to true", 289 ruleEvaluationResults1.get(2).getResult()); 290 291 // ONLY agenda 1 should have been selected 292 assertTrue(TestActionTypeService 293 .actionFired("TestAgenda1::Rule1::TestAction")); 294 assertFalse(TestActionTypeService 295 .actionFired("TestAgenda1::Rule2::TestAction")); 296 assertTrue(TestActionTypeService 297 .actionFired("TestAgenda1::Rule3::TestAction")); 298 299 assertAgendaDidNotExecute(AGENDA2); 300 assertAgendaDidNotExecute(AGENDA3); 301 assertAgendaDidNotExecute(AGENDA4); 302 } 303 304 @Transactional 305 // @Test 306 public void testSelectAgendaByName() { 307 Map<String, String> contextQualifiers = new HashMap<String, String>(); 308 contextQualifiers.put(NAMESPACE_CODE, NAMESPACE2); 309 contextQualifiers.put(NAME, CONTEXT2); 310 contextQualifiers.put(CONTEXT2_QUALIFIER, CONTEXT2_QUALIFIER_VALUE); 311 Map<String, String> agendaQualifiers = new HashMap<String, String>(); 312 313 /* 314 * We'll specifically NOT select this attribute to make sure that 315 * matching only takes place against qualifiers in the selection 316 * criteria 317 */ 318 // agendaQualifiers.put(AgendaDefinition.Constants.EVENT, 319 // EARTHQUAKE_EVENT); 320 321 agendaQualifiers.put(NAME, AGENDA3); 322 DateTime now = new DateTime(); 323 324 SelectionCriteria selectionCriteria = SelectionCriteria.createCriteria( 325 now, contextQualifiers, agendaQualifiers); 326 327 Facts.Builder factsBuilder2 = Facts.Builder.create(); 328 factsBuilder2.addFact(BOOL1, "true"); 329 factsBuilder2.addFact(BOOL2, Boolean.TRUE); 330 factsBuilder2.addFact(CAMPUS_CODE_TERM_NAME, "BL"); 331 factsBuilder2.addFact(PREREQ_TERM_NAME, PREREQ_TERM_VALUE); 332 333 ExecutionOptions xOptions2 = new ExecutionOptions(); 334 xOptions2.setFlag(ExecutionFlag.LOG_EXECUTION, true); 335 336 PerformanceLogger perfLog = new PerformanceLogger(); 337 perfLog.log("starting rule execution 1"); 338 EngineResults eResults1 = KrmsApiServiceLocator.getEngine().execute( 339 selectionCriteria, factsBuilder2.build(), xOptions2); 340 perfLog.log("finished rule execution 1"); 341 List<ResultEvent> rEvents1 = eResults1.getAllResults(); 342 343 List<ResultEvent> ruleEvaluationResults1 = eResults1 344 .getResultsOfType(ResultEvent.RULE_EVALUATED.toString()); 345 346 selectionCriteria = SelectionCriteria.createCriteria(now, 347 contextQualifiers, agendaQualifiers); 348 349 assertEquals("4 rules should have been evaluated", 4, 350 ruleEvaluationResults1.size()); 351 352 assertAgendaDidNotExecute(AGENDA1); 353 assertAgendaDidNotExecute(AGENDA2); 354 355 // ONLY agenda 3 should have been selected 356 assertTrue(TestActionTypeService 357 .actionFired("Agenda3::Rule1::TestAction")); 358 assertFalse(TestActionTypeService 359 .actionFired("Agenda3::Rule2::TestAction")); 360 assertTrue(TestActionTypeService 361 .actionFired("Agenda3::Rule3::TestAction")); 362 363 assertAgendaDidNotExecute(AGENDA4); 364 } 365 366 @Transactional 367 // @Test 368 public void testSelectMultipleAgendasByAttribute() { 369 Map<String, String> contextQualifiers = new HashMap<String, String>(); 370 contextQualifiers.put(NAMESPACE_CODE, NAMESPACE2); 371 contextQualifiers.put(NAME, CONTEXT2); 372 contextQualifiers.put(CONTEXT2_QUALIFIER, CONTEXT2_QUALIFIER_VALUE); 373 374 Map<String, String> agendaQualifiers = new HashMap<String, String>(); 375 agendaQualifiers 376 .put(AgendaDefinition.Constants.EVENT, EARTHQUAKE_EVENT); 377 378 DateTime now = new DateTime(); 379 380 SelectionCriteria selectionCriteria = SelectionCriteria.createCriteria( 381 now, contextQualifiers, agendaQualifiers); 382 383 Facts.Builder factsBuilder2 = Facts.Builder.create(); 384 factsBuilder2.addFact(BOOL1, "true"); 385 factsBuilder2.addFact(BOOL2, Boolean.TRUE); 386 factsBuilder2.addFact(CAMPUS_CODE_TERM_NAME, "BL"); 387 factsBuilder2.addFact(PREREQ_TERM_NAME, PREREQ_TERM_VALUE); 388 389 ExecutionOptions xOptions2 = new ExecutionOptions(); 390 xOptions2.setFlag(ExecutionFlag.LOG_EXECUTION, true); 391 392 PerformanceLogger perfLog = new PerformanceLogger(); 393 perfLog.log("starting rule execution 1"); 394 EngineResults eResults1 = KrmsApiServiceLocator.getEngine().execute( 395 selectionCriteria, factsBuilder2.build(), xOptions2); 396 perfLog.log("finished rule execution 1"); 397 List<ResultEvent> rEvents1 = eResults1.getAllResults(); 398 399 List<ResultEvent> ruleEvaluationResults1 = eResults1 400 .getResultsOfType(ResultEvent.RULE_EVALUATED.toString()); 401 402 selectionCriteria = SelectionCriteria.createCriteria(now, 403 contextQualifiers, agendaQualifiers); 404 405 assertEquals("8 rules should have been evaluated", 8, 406 ruleEvaluationResults1.size()); 407 408 assertAgendaDidNotExecute(AGENDA1); 409 410 // ONLY agendas 2 & 3 should have been selected 411 412 assertTrue(TestActionTypeService 413 .actionFired("Agenda2::Rule1::TestAction")); 414 assertFalse(TestActionTypeService 415 .actionFired("Agenda2::Rule2::TestAction")); 416 assertTrue(TestActionTypeService 417 .actionFired("Agenda2::Rule3::TestAction")); 418 419 assertTrue(TestActionTypeService 420 .actionFired("Agenda3::Rule1::TestAction")); 421 assertFalse(TestActionTypeService 422 .actionFired("Agenda3::Rule2::TestAction")); 423 assertTrue(TestActionTypeService 424 .actionFired("Agenda3::Rule3::TestAction")); 425 426 assertAgendaDidNotExecute(AGENDA4); 427 } 428 429 private void assertAgendaDidNotExecute(String agendaName) { 430 assertFalse(TestActionTypeService.actionFired(agendaName 431 + "::Rule1::TestAction")); 432 assertFalse(TestActionTypeService.actionFired(agendaName 433 + "::Rule2::TestAction")); 434 assertFalse(TestActionTypeService.actionFired(agendaName 435 + "::Rule3::TestAction")); 436 } 437 438 private void createAgendaDefinition(String agendaName, 439 ContextDefinition contextDefinition, String eventName, 440 String nameSpace, KrmsTypeDefinition krmsGenericTypeDefinition) { 441 AgendaDefinition agendaDef = AgendaDefinition.Builder.create(null, 442 agendaName, krmsGenericTypeDefinition.getId(), 443 contextDefinition.getId()).build(); 444 agendaDef = agendaBoService.createAgenda(agendaDef); 445 } 446 447 private void createRulesForAgenda(String agendaName, 448 ContextDefinition contextDefinition, String eventName, 449 String nameSpace, AgendaDefinition agendaDef) { 450 AgendaItemDefinition.Builder agendaItemBuilder1 = AgendaItemDefinition.Builder 451 .create(null, agendaDef.getId()); 452 agendaItemBuilder1.setRuleId(createRuleDefinition1(contextDefinition, 453 agendaName, nameSpace).getId()); 454 455 AgendaItemDefinition.Builder agendaItemBuilder2 = AgendaItemDefinition.Builder 456 .create(null, agendaDef.getId()); 457 agendaItemBuilder1.setAlways(agendaItemBuilder2); 458 agendaItemBuilder2.setRuleId(createRuleDefinition2(contextDefinition, 459 agendaName, nameSpace).getId()); 460 461 AgendaItemDefinition.Builder agendaItemBuilder3 = AgendaItemDefinition.Builder 462 .create(null, agendaDef.getId()); 463 agendaItemBuilder2.setAlways(agendaItemBuilder3); 464 agendaItemBuilder3.setRuleId(createRuleDefinition3(contextDefinition, 465 agendaName, nameSpace).getId()); 466 467 AgendaItemDefinition.Builder agendaItemBuilder4 = AgendaItemDefinition.Builder 468 .create(null, agendaDef.getId()); 469 agendaItemBuilder3.setAlways(agendaItemBuilder4); 470 agendaItemBuilder4.setRuleId(createRuleDefinition4(contextDefinition, 471 agendaName, nameSpace).getId()); 472 473 // String these puppies together. Kind of a PITA because you need the id 474 // from the next item before you insert the previous one 475 AgendaItemDefinition agendaItem4 = agendaBoService 476 .createAgendaItem(agendaItemBuilder4.build()); 477 agendaItemBuilder3.setAlwaysId(agendaItem4.getId()); 478 AgendaItemDefinition agendaItem3 = agendaBoService 479 .createAgendaItem(agendaItemBuilder3.build()); 480 agendaItemBuilder2.setAlwaysId(agendaItem3.getId()); 481 AgendaItemDefinition agendaItem2 = agendaBoService 482 .createAgendaItem(agendaItemBuilder2.build()); 483 agendaItemBuilder1.setAlwaysId(agendaItem2.getId()); 484 AgendaItemDefinition agendaItem1 = agendaBoService 485 .createAgendaItem(agendaItemBuilder1.build()); 486 487 AgendaDefinition.Builder agendaDefBuilder1 = AgendaDefinition.Builder 488 .create(agendaDef); 489 agendaDefBuilder1.setAttributes(Collections.singletonMap("Event", 490 eventName)); 491 agendaDefBuilder1.setFirstItemId(agendaItem1.getId()); 492 agendaDef = agendaDefBuilder1.build(); 493 494 agendaBoService.updateAgenda(agendaDef); 495 } 496 497 private KrmsTypeDefinition createKrmsActionTypeDefinition(String nameSpace) { 498 String ACTION_TYPE_NAME = "KrmsActionResolverType"; 499 KrmsTypeDefinition krmsActionTypeDefinition = krmsTypeRepository 500 .getTypeByName(nameSpace, ACTION_TYPE_NAME); 501 502 if (krmsActionTypeDefinition == null) { 503 KrmsTypeDefinition.Builder krmsActionTypeDefnBuilder = KrmsTypeDefinition.Builder 504 .create(ACTION_TYPE_NAME, nameSpace); 505 krmsActionTypeDefnBuilder.setServiceName("testActionTypeService"); 506 krmsActionTypeDefinition = krmsTypeRepository 507 .createKrmsType(krmsActionTypeDefnBuilder.build()); 508 } 509 510 return krmsActionTypeDefinition; 511 } 512 513 private RuleDefinition createRuleDefinition(String nameSpace, 514 String ruleName, ContextDefinition contextDefinition, 515 LogicalOperator operator, PropositionParametersBuilder... pbs) { 516 RuleDefinition.Builder ruleDefBuilder = RuleDefinition.Builder.create( 517 null, ruleName, nameSpace, null, null); 518 RuleDefinition ruleDef1 = ruleBoService.createRule(ruleDefBuilder 519 .build()); 520 521 PropositionDefinition.Builder parentProposition = PropositionDefinition.Builder 522 .create(null, PropositionType.COMPOUND.getCode(), 523 ruleDef1.getId(), null, null); 524 parentProposition 525 .setCompoundComponents(new ArrayList<PropositionDefinition.Builder>()); 526 527 if (operator != null) { 528 parentProposition.setCompoundOpCode(operator.getCode()); 529 } 530 531 ruleDefBuilder = RuleDefinition.Builder.create(ruleDef1); 532 533 for (PropositionParametersBuilder params : pbs) { 534 535 StringBuilder propositionNameBuilder = new StringBuilder(ruleName); 536 537 propositionNameBuilder.append("::"); 538 for (Object[] param : params.params) { 539 propositionNameBuilder.append(param[0].toString()); 540 propositionNameBuilder.append("--"); 541 } 542 543 PropositionDefinition.Builder propositionBuilder = createPropositionDefinition( 544 propositionNameBuilder.toString(), params, ruleDef1); 545 546 if (pbs.length > 1) { 547 // add it to the compound prop 548 parentProposition.getCompoundComponents().add( 549 propositionBuilder); 550 } else { 551 // if there is only one proposition to build, make it the parent 552 parentProposition = propositionBuilder; 553 } 554 } 555 556 ruleDefBuilder.setProposition(parentProposition); 557 ruleDef1 = ruleDefBuilder.build(); 558 ruleBoService.updateRule(ruleDef1); 559 560 // Action 561 ActionDefinition.Builder actionDefBuilder1 = ActionDefinition.Builder 562 .create(null, ruleName + "::TestAction", nameSpace, 563 createKrmsActionTypeDefinition(nameSpace).getId(), 564 ruleDef1.getId(), 1); 565 ActionDefinition actionDef1 = actionBoService 566 .createAction(actionDefBuilder1.build()); 567 568 return ruleDef1; 569 } 570 571 private RuleDefinition createRuleDefinition1( 572 ContextDefinition contextDefinition, String agendaName, 573 String nameSpace) { 574 575 PropositionParametersBuilder params1 = new PropositionParametersBuilder(); 576 params1.add( 577 createTermDefinition(CAMPUS_CODE_TERM_NAME, String.class, 578 contextDefinition).getId(), 579 PropositionParameterType.TERM); 580 params1.add("QC", PropositionParameterType.CONSTANT); 581 params1.add("=", PropositionParameterType.OPERATOR); 582 583 PropositionParametersBuilder params2 = new PropositionParametersBuilder(); 584 params2.add( 585 createTermDefinition(CAMPUS_CODE_TERM_NAME, String.class, 586 contextDefinition).getId(), 587 PropositionParameterType.TERM); 588 params2.add("BL", PropositionParameterType.CONSTANT); 589 params2.add("=", PropositionParameterType.OPERATOR); 590 591 return createRuleDefinition(nameSpace, agendaName + "::Rule1", 592 contextDefinition, LogicalOperator.OR, params1, params2); 593 } 594 595 private PropositionDefinition.Builder createPropositionDefinition( 596 String propDescription, PropositionParametersBuilder params, 597 RuleDefinition parentRule) { 598 // Proposition for rule 2 599 PropositionDefinition.Builder propositionDefBuilder1 = PropositionDefinition.Builder 600 .create(null, PropositionType.SIMPLE.getCode(), 601 parentRule.getId(), null /* 602 * type code is only for custom 603 * props 604 */, 605 Collections.<PropositionParameter.Builder> emptyList()); 606 propositionDefBuilder1.setDescription(propDescription); 607 608 // PropositionParams for rule 2 609 List<PropositionParameter.Builder> propositionParams1 = params.build(); 610 611 // set the parent proposition so the builder will not puke 612 for (PropositionParameter.Builder propositionParamBuilder : propositionParams1) { 613 propositionParamBuilder.setProposition(propositionDefBuilder1); 614 } 615 616 propositionDefBuilder1.setParameters(propositionParams1); 617 618 return propositionDefBuilder1; 619 } 620 621 private TermDefinition createTermDefinition(String termName, 622 Class termValueType, ContextDefinition contextDefinition) { 623 624 // this may be called more than once, we only want to create one though 625 Map<String, String> queryArgs = new HashMap<String, String>(); 626 queryArgs.put("specification.namespace", 627 contextDefinition.getNamespace()); 628 queryArgs.put("specification.name", termName); 629 TermBo termBo = getBoService() 630 .findByPrimaryKey(TermBo.class, queryArgs); 631 if (termBo != null) { 632 return TermBo.to(termBo); 633 } 634 635 // campusCode TermSpec 636 TermSpecificationDefinition termSpec = TermSpecificationDefinition.Builder 637 .create(null, termName, contextDefinition.getNamespace(), 638 termValueType.getCanonicalName()).build(); 639 640 termSpec = termBoService.createTermSpecification(termSpec); 641 642 // Term 1 643 TermDefinition termDefinition = TermDefinition.Builder.create(null, 644 TermSpecificationDefinition.Builder.create(termSpec), null) 645 .build(); 646 termDefinition = termBoService.createTerm(termDefinition); 647 648 return termDefinition; 649 } 650 651 private RuleDefinition createRuleDefinition2( 652 ContextDefinition contextDefinition, String agendaName, 653 String nameSpace) { 654 655 PropositionParametersBuilder params1 = new PropositionParametersBuilder(); 656 params1.add( 657 createTermDefinition2(contextDefinition, nameSpace).getId(), 658 PropositionParameterType.TERM); 659 params1.add("RESULT1", PropositionParameterType.CONSTANT); 660 params1.add("=", PropositionParameterType.OPERATOR); 661 662 PropositionParametersBuilder params2 = new PropositionParametersBuilder(); 663 params2.add( 664 createTermDefinition2(contextDefinition, nameSpace).getId(), 665 PropositionParameterType.TERM); 666 params2.add("NotGonnaBeEqual", PropositionParameterType.CONSTANT); 667 params2.add("=", PropositionParameterType.OPERATOR); 668 669 return createRuleDefinition(nameSpace, agendaName + "::Rule2", 670 contextDefinition, LogicalOperator.AND, params1, params2); 671 } 672 673 private RuleDefinition createRuleDefinition3( 674 ContextDefinition contextDefinition, String agendaName, 675 String nameSpace) { 676 677 FunctionDefinition gcdFunction = functionBoService 678 .getFunctionByNameAndNamespace("gcd", 679 contextDefinition.getNamespace()); 680 681 if (null == gcdFunction) { 682 // better configure a custom fuction for this 683 // KrmsType for custom function 684 KrmsTypeDefinition.Builder krmsFunctionTypeDefnBuilder = KrmsTypeDefinition.Builder 685 .create("KrmsTestFunctionType", nameSpace); 686 krmsFunctionTypeDefnBuilder 687 .setServiceName("testFunctionTypeService"); 688 KrmsTypeDefinition krmsFunctionTypeDefinition = krmsTypeRepository 689 .createKrmsType(krmsFunctionTypeDefnBuilder.build()); 690 691 FunctionDefinition.Builder functionBuilder = FunctionDefinition.Builder 692 .create(contextDefinition.getNamespace(), "gcd", 693 Integer.class.getName(), 694 krmsFunctionTypeDefinition.getId()); 695 696 functionBuilder.getParameters().add( 697 FunctionParameterDefinition.Builder.create("arg0", 698 Integer.class.getName(), 0)); 699 functionBuilder.getParameters().add( 700 FunctionParameterDefinition.Builder.create("arg1", 701 Integer.class.getName(), 1)); 702 functionBuilder.setReturnType(Integer.class.getName()); 703 704 gcdFunction = functionBoService.createFunction(functionBuilder 705 .build()); 706 } 707 708 PropositionParametersBuilder params = new PropositionParametersBuilder(); 709 710 // leverage our stack based evaluation in reverse polish notation 711 params.add("1024", PropositionParameterType.CONSTANT); 712 params.add("768", PropositionParameterType.CONSTANT); 713 params.add(gcdFunction.getId(), PropositionParameterType.FUNCTION); // this 714 // should 715 // evaluate 716 // first: 717 // gcd(1024, 718 // 768) 719 params.add("256", PropositionParameterType.CONSTANT); 720 params.add("=", PropositionParameterType.OPERATOR); // this should 721 // evaluate second: 722 // gcdResult == 256 723 724 return createRuleDefinition(nameSpace, agendaName + "::Rule3", 725 contextDefinition, null, params); 726 } 727 728 private RuleDefinition createRuleDefinition4( 729 ContextDefinition contextDefinition, String agendaName, 730 String nameSpace) { 731 732 PropositionParametersBuilder params1 = new PropositionParametersBuilder(); 733 params1.add( 734 createTermDefinition(BOOL1, Boolean.class, contextDefinition) 735 .getId(), PropositionParameterType.TERM); 736 params1.add( 737 createTermDefinition(BOOL2, Boolean.class, contextDefinition) 738 .getId(), PropositionParameterType.TERM); 739 params1.add("=", PropositionParameterType.OPERATOR); 740 741 PropositionParametersBuilder params2 = new PropositionParametersBuilder(); 742 params2.add( 743 createTermDefinition(BOOL2, Boolean.class, contextDefinition) 744 .getId(), PropositionParameterType.TERM); 745 params2.add( 746 createTermDefinition(BOOL1, Boolean.class, contextDefinition) 747 .getId(), PropositionParameterType.TERM); 748 params2.add("=", PropositionParameterType.OPERATOR); 749 750 return createRuleDefinition(nameSpace, agendaName + "::Rule4", 751 contextDefinition, LogicalOperator.AND, params1, params2); 752 } 753 754 private TermDefinition createTermDefinition2( 755 ContextDefinition contextDefinition, String nameSpace) { 756 757 Map<String, String> queryArgs = new HashMap<String, String>(); 758 queryArgs.put("specification.namespace", 759 contextDefinition.getNamespace()); 760 queryArgs.put("specification.name", "outputTermSpec"); 761 TermBo result = getBoService() 762 .findByPrimaryKey(TermBo.class, queryArgs); 763 if (result != null) 764 return TermBo.to(result); 765 766 // output TermSpec 767 TermSpecificationDefinition outputTermSpec = TermSpecificationDefinition.Builder 768 .create(null, "outputTermSpec", 769 contextDefinition.getNamespace(), "java.lang.String") 770 .build(); 771 outputTermSpec = termBoService.createTermSpecification(outputTermSpec); 772 773 // prereq TermSpec 774 TermSpecificationDefinition prereqTermSpec = TermSpecificationDefinition.Builder 775 .create(null, PREREQ_TERM_NAME, 776 contextDefinition.getNamespace(), "java.lang.String") 777 .build(); 778 prereqTermSpec = termBoService.createTermSpecification(prereqTermSpec); 779 780 // Term Param 781 TermParameterDefinition.Builder termParamBuilder2 = TermParameterDefinition.Builder 782 .create(null, null, "testParamName", "testParamValue"); 783 784 // Term 785 TermDefinition termDefinition2 = TermDefinition.Builder.create(null, 786 TermSpecificationDefinition.Builder.create(outputTermSpec), 787 Collections.singletonList(termParamBuilder2)).build(); 788 termDefinition2 = termBoService.createTerm(termDefinition2); 789 790 // KrmsType for TermResolver 791 KrmsTypeDefinition.Builder krmsTermResolverTypeDefnBuilder = KrmsTypeDefinition.Builder 792 .create("KrmsTestResolverType", nameSpace); 793 krmsTermResolverTypeDefnBuilder 794 .setServiceName("testTermResolverTypeService"); 795 796 KrmsTypeDefinition krmsTermResolverTypeDefinition = krmsTypeRepository 797 .createKrmsType(krmsTermResolverTypeDefnBuilder.build()); 798 799 // TermResolver 800 TermResolverDefinition termResolverDef = TermResolverDefinition.Builder 801 .create(null, 802 contextDefinition.getNamespace(), 803 "testResolver1", 804 krmsTermResolverTypeDefinition.getId(), 805 TermSpecificationDefinition.Builder 806 .create(outputTermSpec), 807 Collections 808 .singleton(TermSpecificationDefinition.Builder 809 .create(prereqTermSpec)), null, 810 Collections.singleton("testParamName")).build(); 811 termResolverDef = termBoService.createTermResolver(termResolverDef); 812 813 return termDefinition2; 814 } 815 816 private static class PropositionParametersBuilder { 817 818 // poor OOD but this is quick and dirty :-P 819 private List<Object[]> params = new ArrayList<Object[]>(); 820 821 public PropositionParametersBuilder add(String value, 822 PropositionParameterType type) { 823 if (type == null) 824 throw new IllegalArgumentException("type must not be null"); 825 params.add(new Object[] { value, type }); 826 return this; 827 } 828 829 public List<PropositionParameter.Builder> build() { 830 int seqCounter = 0; 831 832 List<PropositionParameter.Builder> results = new ArrayList<PropositionParameter.Builder>(); 833 834 for (Object[] param : params) { 835 results.add(PropositionParameter.Builder.create(null, null, 836 (String) param[0], 837 ((PropositionParameterType) param[1]).getCode(), 838 seqCounter++)); 839 } 840 841 return results; 842 } 843 } 844 845 @Override 846 protected List<Lifecycle> getSuiteLifecycles() { 847 // TODO Auto-generated method stub 848 List<Lifecycle> steps = super.getSuiteLifecycles(); 849 int cnt = -1; 850 for (int i = 0; i < steps.size(); i++) { 851 if (steps.get(i) instanceof ClearDatabaseLifecycle) { 852 cnt = i; 853 } 854 } 855 if (cnt > 0) { 856 steps.remove(cnt + 1); 857 steps.remove(cnt); 858 859 } 860 return steps; 861 } 862 863 protected void createAllLumTermDefinitions(String nameSpace) { 864 // Create all the terms... 865 createNumberOfCreditsTermDefinition(nameSpace); 866 createDeptOrgNumberTermDefinition(nameSpace); 867 createProposedCourseTermDefinition(nameSpace); 868 createApprovedCourseTermDefinition(nameSpace); 869 } 870 871 // 872 private void createNumberOfCreditsTermDefinition(String nameSpace) { 873 // TODO NINA Add the context link to the Term Specification 874 TermSpecificationDefinition termSpec = createTermSpecification(nameSpace, TERM_SPEC_CREDITS); 875 876 TermDefinition termDefinition = TermDefinition.Builder.create( 877 null, 878 TermSpecificationDefinition.Builder.create(termSpec), null).build(); 879 880 termDefinition = termBoService.createTerm(termDefinition); 881 882 } 883 884 private TermSpecificationDefinition createTermSpecification(String nameSpace, String termSpecName) { 885 Map<String, String> queryArgs = new HashMap<String, String>(); 886 queryArgs.put("namespace", nameSpace); 887 queryArgs.put("name", termSpecName); 888 TermSpecificationBo termSpecBo = getBoService().findByPrimaryKey( 889 TermSpecificationBo.class, queryArgs); 890 // 891 TermSpecificationDefinition termSpec = null; 892 if (termSpecBo == null) { 893 termSpec = TermSpecificationDefinition.Builder 894 .create(null, termSpecName, nameSpace, 895 String.class.getCanonicalName()).build(); 896 897 termSpec = termBoService.createTermSpecification(termSpec); 898 899 } else { 900 termSpec = termSpecBo.to(termSpecBo); 901 } 902 return termSpec; 903 } 904 905 private void createDeptOrgNumberTermDefinition(String nameSpace) { 906 907 Map<String, String> queryArgs = new HashMap<String, String>(); 908 queryArgs.put("namespace", nameSpace); 909 queryArgs.put("name", TERM_SPEC_ORG_NUMBER); 910 TermSpecificationBo termSpecBo = getBoService().findByPrimaryKey( 911 TermSpecificationBo.class, queryArgs); 912 // 913 TermSpecificationDefinition termSpec = null; 914 if (termSpecBo == null) { 915 termSpec = TermSpecificationDefinition.Builder 916 .create(null, TERM_SPEC_ORG_NUMBER, nameSpace, 917 String.class.getCanonicalName()).build(); 918 919 termSpec = termBoService.createTermSpecification(termSpec); 920 921 } else { 922 termSpec = termSpecBo.to(termSpecBo); 923 } 924 925 TermDefinition termDefinition = TermDefinition.Builder.create( 926 null, 927 TermSpecificationDefinition.Builder.create(termSpec), null) 928 .build(); 929 930 termDefinition = termBoService.createTerm(termDefinition); 931 932 } 933 934 private void createProposedCourseTermDefinition(String nameSpace) { 935 936 Map<String, String> queryArgs = new HashMap<String, String>(); 937 queryArgs.put("namespace", nameSpace); 938 queryArgs.put("name", TERM_SPEC_COURSE); 939 TermSpecificationBo termSpecBo = getBoService().findByPrimaryKey( 940 TermSpecificationBo.class, queryArgs); 941 // 942 TermSpecificationDefinition termSpec = null; 943 if (termSpecBo == null) { 944 termSpec = TermSpecificationDefinition.Builder 945 .create(null, TERM_SPEC_COURSE, nameSpace, 946 String.class.getCanonicalName()).build(); 947 948 termSpec = termBoService.createTermSpecification(termSpec); 949 950 } else { 951 termSpec = termSpecBo.to(termSpecBo); 952 } 953 954 TermDefinition termDefinition = TermDefinition.Builder.create( 955 null, 956 TermSpecificationDefinition.Builder.create(termSpec), null) 957 .build(); 958 959 termDefinition = termBoService.createTerm(termDefinition); 960 961 } 962 963 private void createApprovedCourseTermDefinition(String nameSpace) { 964 965 Map<String, String> queryArgs = new HashMap<String, String>(); 966 queryArgs.put("namespace", nameSpace); 967 queryArgs.put("name", TERM_SPEC_COURSE); 968 TermSpecificationBo termSpecBo = getBoService().findByPrimaryKey( 969 TermSpecificationBo.class, queryArgs); 970 // 971 TermSpecificationDefinition termSpec = null; 972 if (termSpecBo == null) { 973 termSpec = TermSpecificationDefinition.Builder 974 .create(null, TERM_SPEC_COURSE, nameSpace, 975 String.class.getCanonicalName()).build(); 976 977 termSpec = termBoService.createTermSpecification(termSpec); 978 979 } else { 980 termSpec = termSpecBo.to(termSpecBo); 981 } 982 983 TermDefinition termDefinition = TermDefinition.Builder.create( 984 null, 985 TermSpecificationDefinition.Builder.create(termSpec), null) 986 .build(); 987 988 termDefinition = termBoService.createTerm(termDefinition); 989 990 } 991 }