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    }