View Javadoc
1   /*
2    * To change this template, choose Tools | Templates
3    * and open the template in the editor.
4    */
5   package org.kuali.rice.krms.impl.repository;
6   
7   import java.util.ArrayList;
8   import java.util.Date;
9   import java.util.LinkedHashMap;
10  import java.util.LinkedHashSet;
11  import java.util.List;
12  import java.util.Map;
13  import java.util.Set;
14  import javax.xml.namespace.QName;
15  import org.junit.After;
16  import org.junit.AfterClass;
17  import static org.junit.Assert.*;
18  import org.junit.Before;
19  import org.junit.BeforeClass;
20  import org.junit.Test;
21  import org.junit.Ignore;
22  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
23  import org.kuali.rice.krms.api.repository.LogicalOperator;
24  import org.kuali.rice.krms.api.repository.RuleManagementService;
25  import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
26  import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
27  import org.kuali.rice.krms.api.repository.context.ContextDefinition;
28  import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
29  import org.kuali.rice.krms.api.repository.language.NaturalLanguageUsage;
30  import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
31  import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
32  import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType;
33  import org.kuali.rice.krms.api.repository.proposition.PropositionType;
34  import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
35  import org.kuali.rice.krms.api.repository.term.TermDefinition;
36  import org.kuali.rice.krms.api.repository.term.TermParameterDefinition;
37  import org.kuali.rice.krms.api.repository.term.TermRepositoryService;
38  import org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition;
39  import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
40  import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService;
41  import org.kuali.rice.krms.impl.repository.mock.KrmsConfigurationLoader;
42  import org.kuali.student.common.util.UUIDHelper;
43  import org.kuali.student.r2.common.dto.ContextInfo;
44  import org.kuali.student.r2.common.exceptions.*;
45  import org.kuali.student.r2.common.util.constants.LuiServiceConstants;
46  import org.kuali.student.r2.core.constants.KSKRMSServiceConstants;
47  import org.kuali.student.r2.core.process.krms.KSKRMSTestCase;
48  import org.kuali.student.r2.core.versionmanagement.dto.VersionDisplayInfo;
49  import org.kuali.student.r2.lum.clu.dto.CluInfo;
50  import org.kuali.student.r2.lum.clu.dto.CluSetInfo;
51  import org.kuali.student.r2.lum.clu.service.CluService;
52  import org.kuali.student.r2.lum.lu.service.impl.CluDataLoader;
53  import org.kuali.student.r2.lum.lu.service.impl.CluServiceMockImpl;
54  import org.kuali.student.r2.lum.util.constants.CluServiceConstants;
55  import java.util.Arrays;
56  import org.kuali.rice.krms.api.repository.reference.ReferenceObjectBinding;
57  import org.kuali.rice.krms.impl.util.KrmsRuleManagementCopyMethods;
58  import org.kuali.rice.krms.impl.util.KrmsRuleManagementCopyMethodsImpl;
59  
60  /**
61   *
62   * @author nwright
63   */
64  // TODO: KSENROLL-7265  remove ignore per larry's request that all @Ignore's have an associated jira 
65  @Ignore
66  public class RuleManagementServiceImplTest extends KSKRMSTestCase {
67  
68      private KrmsTypeRepositoryService krmsTypeRepositoryService = null;
69      private RuleManagementService ruleManagementService = null;
70      private TermRepositoryService termRepositoryService = null;
71      private CluService cluService = null;
72      private KrmsRuleManagementCopyMethods krmsRuleManagementCopyMethods = null;
73  
74      @BeforeClass
75      public static void setUpClass() {
76      }
77  
78      @AfterClass
79      public static void tearDownClass() {
80      }
81      private ContextInfo contextInfo;
82  
83      @Before
84      public void setUp() throws Exception {
85          super.setUp();
86          contextInfo = new ContextInfo();
87          contextInfo.setPrincipalId("TESTUSER");
88          contextInfo.setCurrentDate(new Date());
89  
90          this.krmsTypeRepositoryService = (KrmsTypeRepositoryService) GlobalResourceLoader.getService(QName.valueOf("krmsTypeRepositoryService"));
91          this.termRepositoryService = (TermRepositoryService) GlobalResourceLoader.getService(QName.valueOf("termRepositoryService"));
92          this.ruleManagementService = (RuleManagementService) GlobalResourceLoader.getService(QName.valueOf("ruleManagementService"));
93          KrmsRuleManagementCopyMethodsImpl copyImpl = new KrmsRuleManagementCopyMethodsImpl();
94  //        copyImpl.setKrmsTypeRepositoryService(krmsTypeRepositoryService);
95          copyImpl.setRuleManagementService(ruleManagementService);
96          this.krmsRuleManagementCopyMethods = copyImpl;
97          KrmsConfigurationLoader loader = new KrmsConfigurationLoader();
98  //        loader.setKrmsTypeRepositoryService(this.krmsTypeRepositoryService);
99  //        loader.setRuleManagementService(this.ruleManagementService);
100 //        loader.setTermRepositoryService(this.termRepositoryService);
101 //        loader.loadConfiguration();
102 
103         this.cluService = new CluServiceMockImpl();
104         CluDataLoader cluDataLoader = new CluDataLoader();
105         cluDataLoader.setCluService(cluService);
106         cluDataLoader.setContextInfo(contextInfo);
107         cluDataLoader.load();
108 
109     }
110 
111     @After
112     public void tearDown() {
113     }
114 
115     @Test
116     public void testCreateSimpleProposition() {
117         this.createCheckBasicAgendaFor1OfCluSet23();
118     }
119 
120     @Test
121     public void testCopyingSimpleProposition() {
122         String namespace = KSKRMSServiceConstants.NAMESPACE_CODE;
123         String fromReferenceDiscriminatorType = CluServiceConstants.CREDIT_COURSE_LU_TYPE_KEY;
124         String fromReferenceObjectId = "COURSE1";
125         String toReferenceDiscriminatorType = LuiServiceConstants.COURSE_OFFERING_TYPE_KEY;
126         String toReferenceObjectId = "COURSEOFFERING1";
127 
128         // delete any rules if there are any
129         int bindingsDeleted = this.krmsRuleManagementCopyMethods.deleteReferenceObjectBindingsCascade(fromReferenceDiscriminatorType, fromReferenceObjectId);
130         System.out.println("number of existing bindings deleted for " + fromReferenceObjectId + " count=" + bindingsDeleted);
131         bindingsDeleted = this.krmsRuleManagementCopyMethods.deleteReferenceObjectBindingsCascade(toReferenceDiscriminatorType, toReferenceObjectId);
132         System.out.println("number of existing bindings deleted for " + toReferenceObjectId + " count=" + bindingsDeleted);
133 
134 
135         AgendaDefinition agenda = this.createCheckBasicAgendaFor1OfCluSet23();
136         String krmsDiscriminatorType = KSKRMSServiceConstants.KRMS_DISCRIMINATOR_TYPE_AGENDA;
137         String krmsObjectId = agenda.getId();
138 
139         ReferenceObjectBinding.Builder bindingBldr = ReferenceObjectBinding.Builder.create(krmsDiscriminatorType,
140                 krmsObjectId,
141                 namespace,
142                 fromReferenceDiscriminatorType,
143                 fromReferenceObjectId);
144         ReferenceObjectBinding binding = this.ruleManagementService.createReferenceObjectBinding(bindingBldr.build());
145 
146         List<String> optionKeys = new ArrayList<String>();
147         List<ReferenceObjectBinding> list = null;
148         try {
149             list = this.krmsRuleManagementCopyMethods.deepCopyReferenceObjectBindingsFromTo(
150                     fromReferenceDiscriminatorType,
151                     fromReferenceObjectId,
152                     toReferenceDiscriminatorType,
153                     toReferenceObjectId,
154                     optionKeys);
155         } catch (Exception e) {
156             throw new RuntimeException(e);
157         }
158 
159         assertNotNull(list);
160         assertEquals(1, list.size());
161         ReferenceObjectBinding copy = list.get(0);
162         assertEquals(toReferenceObjectId, copy.getReferenceObjectId());
163         assertEquals(LuiServiceConstants.COURSE_OFFERING_TYPE_KEY, copy.getReferenceDiscriminatorType());
164         checkCopy(binding, list.get(0));
165 
166 
167         // delete any rules that were created
168         bindingsDeleted = this.krmsRuleManagementCopyMethods.deleteReferenceObjectBindingsCascade(fromReferenceDiscriminatorType,
169                 fromReferenceObjectId);
170         System.out.println("number of existing bindings deleted for " + fromReferenceObjectId + " count=" + bindingsDeleted);
171         bindingsDeleted = this.krmsRuleManagementCopyMethods.deleteReferenceObjectBindingsCascade(toReferenceDiscriminatorType,
172                 toReferenceObjectId);
173         System.out.println("number of existing bindings deleted for " + toReferenceObjectId + " count=" + bindingsDeleted);
174     }
175 
176     @Test
177     public void testCopyingCompoundProposition() {
178         String namespace = KSKRMSServiceConstants.NAMESPACE_CODE;
179         // TODO: KSENROLL-7291 convert the discriminator type to use the ref object uri instead of the lu type type
180 //        String fromReferenceDiscriminatorType = CourseServiceConstants.COURSE_NAMESPACE_URI;
181         String fromReferenceDiscriminatorType = CluServiceConstants.CREDIT_COURSE_LU_TYPE_KEY;
182         String fromReferenceObjectId = "COURSE2";
183         // TODO: KSENROLL-7291 convert the discriminator type to use the ref object uri instead of the lu type type
184 //        String toReferenceDiscriminatorType = CourseOfferingServiceConstants.REF_OBJECT_URI_COURSE_OFFERING,
185         String toReferenceDiscriminatorType = LuiServiceConstants.COURSE_OFFERING_TYPE_KEY;
186         String toReferenceObjectId = "COURSEOFFERING2";
187 
188         // delete any rules if there are any
189         int bindingsDeleted = this.krmsRuleManagementCopyMethods.deleteReferenceObjectBindingsCascade(fromReferenceDiscriminatorType,
190                 fromReferenceObjectId);
191         System.out.println("number of existing bindings deleted for " + fromReferenceObjectId + " count=" + bindingsDeleted);
192         bindingsDeleted = this.krmsRuleManagementCopyMethods.deleteReferenceObjectBindingsCascade(toReferenceDiscriminatorType,
193                 toReferenceObjectId);
194         System.out.println("number of existing bindings deleted for " + toReferenceObjectId + " count=" + bindingsDeleted);
195 
196 
197         ContextDefinition context = this.findCreateContext();
198         AgendaDefinition agenda = createCheckEmptyAgenda(context);
199         agenda = updateCheckAgendaFirstItemAddingEmptyRule(agenda);
200 
201         PropositionDefinition.Builder propBldr1 = this.constructFreeFormTextPropositionBulider("My first Text Value");
202         CluSetInfo cluSet = this.findCreateCluSet23();
203         PropositionDefinition.Builder propBldr2 = createNOfCluSetPropositionBuilder(1, cluSet);
204         cluSet = this.findCreateCluSet456();
205         PropositionDefinition.Builder propBldr3 = createNOfCluSetPropositionBuilder(2, cluSet);
206 
207         PropositionDefinition.Builder andPropBldr = this.makeAndCompoundProposition(propBldr2, propBldr3);
208         PropositionDefinition.Builder orPropBldr = this.makeOrCompoundProposition(propBldr1, andPropBldr);
209         agenda = updateCheckFirstItemSettingPropositionOnRule(agenda, orPropBldr);
210 
211         String krmsDiscriminatorType = KSKRMSServiceConstants.KRMS_DISCRIMINATOR_TYPE_AGENDA;
212         String krmsObjectId = agenda.getId();
213 
214         ReferenceObjectBinding.Builder bindingBldr = ReferenceObjectBinding.Builder.create(krmsDiscriminatorType,
215                 krmsObjectId,
216                 namespace,
217                 fromReferenceDiscriminatorType,
218                 fromReferenceObjectId);
219         ReferenceObjectBinding binding = this.ruleManagementService.createReferenceObjectBinding(bindingBldr.build());
220 
221         List<String> optionKeys = new ArrayList<String>();
222         List<ReferenceObjectBinding> list = null;
223         try {
224             list = this.krmsRuleManagementCopyMethods.deepCopyReferenceObjectBindingsFromTo(
225                     fromReferenceDiscriminatorType,
226                     fromReferenceObjectId,
227                     toReferenceDiscriminatorType,
228                     toReferenceObjectId,
229                     optionKeys);
230         } catch (Exception e) {
231             throw new RuntimeException(e);
232         }
233 
234         assertNotNull(list);
235         assertEquals(1, list.size());
236         ReferenceObjectBinding copy = list.get(0);
237         assertEquals(toReferenceObjectId, copy.getReferenceObjectId());
238         assertEquals(LuiServiceConstants.COURSE_OFFERING_TYPE_KEY, copy.getReferenceDiscriminatorType());
239         checkCopy(binding, list.get(0));
240 
241         // delete any rules that were created
242         bindingsDeleted = this.krmsRuleManagementCopyMethods.deleteReferenceObjectBindingsCascade(fromReferenceDiscriminatorType,
243                 fromReferenceObjectId);
244         System.out.println("number of existing bindings deleted for " + fromReferenceObjectId + " count=" + bindingsDeleted);
245         bindingsDeleted = this.krmsRuleManagementCopyMethods.deleteReferenceObjectBindingsCascade(toReferenceDiscriminatorType,
246                 toReferenceObjectId);
247         System.out.println("number of existing bindings deleted for " + toReferenceObjectId + " count=" + bindingsDeleted);
248 
249     }
250 
251     private void checkCopy(ReferenceObjectBinding orig, ReferenceObjectBinding copy) {
252         assertNotEquals(orig.getId(), copy.getId());
253         assertEquals(orig.getKrmsDiscriminatorType(), copy.getKrmsDiscriminatorType());
254         assertNotEquals(orig.getKrmsObjectId(), copy.getKrmsObjectId());
255         AgendaDefinition origAgenda = this.ruleManagementService.getAgenda(orig.getKrmsObjectId());
256         AgendaDefinition copyAgenda = this.ruleManagementService.getAgenda(copy.getKrmsObjectId());
257         checkCopy(origAgenda, copyAgenda);
258     }
259 
260     private void checkCopy(AgendaDefinition orig, AgendaDefinition copy) {
261         if (orig == null && copy == null) {
262             return;
263         }
264         assertNotEquals(orig.getId(), copy.getId());
265         assertEquals(orig.getContextId(), copy.getContextId());
266         // names have to be different but shouldn't they be similar?
267         assertNotEquals(orig.getName(), copy.getName());
268         assertEquals(orig.getTypeId(), copy.getTypeId());
269         assertEquals(orig.isActive(), copy.isActive());
270         assertEquals(orig.getAttributes(), copy.getAttributes());
271         assertNotEquals(orig.getFirstItemId(), copy.getFirstItemId());
272         AgendaItemDefinition origItem = this.ruleManagementService.getAgendaItem(orig.getFirstItemId());
273         AgendaItemDefinition copyItem = this.ruleManagementService.getAgendaItem(copy.getFirstItemId());
274         checkCopy(origItem, copyItem);
275     }
276 
277     private void checkCopy(AgendaItemDefinition orig, AgendaItemDefinition copy) {
278         if (orig == null && copy == null) {
279             return;
280         }
281         assertNotEquals(orig.getId(), copy.getId());
282         assertNotEquals(orig.getAgendaId(), copy.getAgendaId());
283         checkCopy(orig.getAlwaysId(), copy.getAlwaysId());
284         checkCopy(orig.getAlways(), copy.getAlways());
285         checkCopy(orig.getRuleId(), copy.getRuleId());
286         checkCopy(orig.getRule(), copy.getRule());
287         checkCopy(orig.getSubAgendaId(), copy.getSubAgendaId());
288         checkCopy(orig.getSubAgenda(), copy.getSubAgenda());
289         checkCopy(orig.getWhenFalseId(), copy.getWhenFalseId());
290         checkCopy(orig.getWhenFalse(), copy.getWhenFalse());
291         checkCopy(orig.getWhenTrueId(), copy.getWhenTrueId());
292         checkCopy(orig.getWhenTrue(), copy.getWhenTrue());
293     }
294 
295     private void checkCopy(String orig, String copy) {
296         if (orig == null && copy == null) {
297             return;
298         }
299         assertNotEquals(orig, copy);
300     }
301 
302     private void checkCopy(RuleDefinition orig, RuleDefinition copy) {
303         if (orig == null && copy == null) {
304             return;
305         }
306         assertNotEquals(orig.getId(), copy.getId());
307         assertEquals(orig.getAttributes(), copy.getAttributes());
308         assertEquals(orig.getActions(), copy.getActions());
309         assertEquals(orig.getDescription(), copy.getDescription());
310         // names have to be different but shouldn't they be similar?
311         assertNotEquals(orig.getName(), copy.getName());
312         assertEquals(orig.getNamespace(), copy.getNamespace());
313         if (orig.getPropId() != null) {
314             checkCopy(orig.getPropId(), copy.getPropId());
315         }
316         checkCopy(orig.getProposition(), copy.getProposition());
317         assertEquals(orig.getTypeId(), copy.getTypeId());
318         assertEquals(orig.isActive(), copy.isActive());
319     }
320 
321     private void checkCopy(PropositionDefinition orig, PropositionDefinition copy) {
322         if (orig == null && copy == null) {
323             return;
324         }
325         assertNotEquals(orig.getId(), copy.getId());
326         assertNotEquals(orig.getRuleId(), copy.getRuleId());
327         assertEquals(orig.getTypeId(), copy.getTypeId());
328         assertEquals(orig.getDescription(), copy.getDescription());
329         assertEquals(orig.getPropositionTypeCode(), copy.getPropositionTypeCode());
330         assertEquals(orig.getCompoundOpCode(), copy.getCompoundOpCode());
331         assertEquals(orig.getCompoundSequenceNumber(), copy.getCompoundSequenceNumber());
332         if (orig.getCompoundComponents() != null) {
333             assertEquals(orig.getCompoundComponents().size(), copy.getCompoundComponents().size());
334             for (int i = 0; i < orig.getCompoundComponents().size(); i++) {
335                 PropositionDefinition origCompoundComponent = orig.getCompoundComponents().get(i);
336                 PropositionDefinition copyCompoundComponent = copy.getCompoundComponents().get(i);
337                 checkCopy(origCompoundComponent, copyCompoundComponent);
338             }
339         }
340         if (orig.getParameters() != null) {
341             assertEquals(orig.getParameters().size(), copy.getParameters().size());
342             for (int i = 0; i < orig.getParameters().size(); i++) {
343                 PropositionParameter origParam = orig.getParameters().get(i);
344                 PropositionParameter copyParam = copy.getParameters().get(i);
345                 checkCopy(origParam, copyParam);
346             }
347         }
348     }
349 
350     private void checkCopy(PropositionParameter orig, PropositionParameter copy) {
351         if (orig == null && copy == null) {
352             return;
353         }
354         assertNotEquals(orig.getId(), copy.getId());
355         assertEquals(orig.getParameterType(), copy.getParameterType());
356         assertNotEquals(orig.getPropId(), copy.getPropId());
357         assertEquals(orig.getSequenceNumber(), copy.getSequenceNumber());
358         if (orig.getParameterType().equals(PropositionParameterType.TERM.getCode())) {
359             checkCopy(orig.getTermValue(), copy.getTermValue());
360         } else {
361             assertEquals(orig.getValue(), copy.getValue());
362             assertNull (copy.getTermValue());
363         }
364     }
365 
366     private void checkCopy(TermDefinition orig, TermDefinition copy) {
367         if (orig == null && copy == null) {
368             return;
369         }
370         assertNotEquals(orig.getId(), copy.getId());
371         assertEquals(orig.getDescription(), copy.getDescription());
372         checkCopy(orig.getSpecification(), copy.getSpecification());
373         if (orig.getParameters() != null) {
374             assertEquals(orig.getParameters().size(), copy.getParameters().size());
375             // Might have order the lists by Name to make sure they compare properly
376             for (int i = 0; i < orig.getParameters().size(); i++) {
377                 TermParameterDefinition origParam = orig.getParameters().get(i);
378                 TermParameterDefinition copyParam = copy.getParameters().get(i);
379                 checkCopy(origParam, copyParam);
380             }
381         }
382     }
383 
384     private void checkCopy(TermSpecificationDefinition orig, TermSpecificationDefinition copy) {
385         if (orig == null && copy == null) {
386             return;
387         }
388         // term spec should NOT be copied so the ids should be the same!
389         assertEquals(orig.getId(), copy.getId());
390         assertEquals(orig.getDescription(), copy.getDescription());
391         assertEquals(orig.getName(), copy.getName());
392         assertEquals(orig.getNamespace(), copy.getNamespace());
393         assertEquals(orig.getDescription(), copy.getDescription());
394     }
395 
396     private void checkCopy(TermParameterDefinition orig, TermParameterDefinition copy) {
397         if (orig == null && copy == null) {
398             return;
399         }
400         // term spec should NOT be copied so the ids should be the same!
401         assertNotEquals(orig.getId(), copy.getId());
402         assertNotEquals(orig.getTermId(), copy.getTermId());
403         assertEquals(orig.getName(), copy.getName());
404         assertEquals(orig.getValue(), copy.getValue());
405     }
406 
407     @Test
408     public void testBasicCreateCompoundProposition() {
409         ContextDefinition context = this.findCreateContext();
410         AgendaDefinition agenda = createCheckEmptyAgenda(context);
411         agenda = updateCheckAgendaFirstItemAddingEmptyRule(agenda);
412 
413         PropositionDefinition.Builder propBldr1 = this.constructFreeFormTextPropositionBulider("My first Text Value");
414         CluSetInfo cluSet = this.findCreateCluSet23();
415         PropositionDefinition.Builder propBldr2 = createNOfCluSetPropositionBuilder(1, cluSet);
416         cluSet = this.findCreateCluSet456();
417         PropositionDefinition.Builder propBldr3 = createNOfCluSetPropositionBuilder(2, cluSet);
418 
419         PropositionDefinition.Builder andPropBldr = this.makeAndCompoundProposition(propBldr2, propBldr3);
420         PropositionDefinition.Builder orPropBldr = this.makeOrCompoundProposition(propBldr1, andPropBldr);
421         agenda = updateCheckFirstItemSettingPropositionOnRule(agenda, orPropBldr);
422     }
423 
424     @Test
425     public void testChangeFromSimple2CompoundProposition() {
426         ContextDefinition context = this.findCreateContext();
427         AgendaDefinition agenda = createCheckEmptyAgenda(context);
428         agenda = updateCheckAgendaFirstItemAddingEmptyRule(agenda);
429 
430         PropositionDefinition.Builder propBldr1 = this.constructFreeFormTextPropositionBulider("My first Text Value");
431         CluSetInfo cluSet = this.findCreateCluSet23();
432         PropositionDefinition.Builder propBldr2 = createNOfCluSetPropositionBuilder(1, cluSet);
433 
434         cluSet = this.findCreateCluSet456();
435         PropositionDefinition.Builder propBldr3 = createNOfCluSetPropositionBuilder(2, cluSet);
436 
437         agenda = updateCheckFirstItemSettingPropositionOnRule(agenda, propBldr3);
438 
439         AgendaItemDefinition firstItem = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
440         PropositionDefinition prop = firstItem.getRule().getProposition();
441         propBldr3 = PropositionDefinition.Builder.create(prop);
442         PropositionDefinition.Builder andPropBldr = this.makeAndCompoundProposition(propBldr2, propBldr3);
443         PropositionDefinition.Builder orPropBldr = this.makeOrCompoundProposition(propBldr1, andPropBldr);
444         agenda = updateCheckFirstItemSettingPropositionOnRule(agenda, orPropBldr);
445     }
446 
447     private PropositionDefinition.Builder makeAndCompoundProposition(PropositionDefinition.Builder... childPropBldrs) {
448         String propId = null;
449         String propTypeCode = PropositionType.COMPOUND.getCode();
450         String ruleId = null;
451         KrmsTypeDefinition type = this.krmsTypeRepositoryService.getTypeByName(KSKRMSServiceConstants.NAMESPACE_CODE,
452                 KSKRMSServiceConstants.PROPOSITION_TYPE_COMPOUND_AND);
453         String typeId = type.getId();
454         List<PropositionParameter.Builder> parameters = new ArrayList<PropositionParameter.Builder>();
455         PropositionDefinition.Builder mainBldr = PropositionDefinition.Builder.create(propId, propTypeCode, ruleId, typeId, parameters);
456         mainBldr.setCompoundOpCode(LogicalOperator.AND.getCode());
457         List<PropositionDefinition.Builder> childList = Arrays.asList(childPropBldrs);
458 //        System.out.println ("order for AND is:");
459 //        for (PropositionDefinition.Builder childBldr : childList) {
460 //            System.out.println ("order is " + childBldr);
461 //        }
462         mainBldr.setCompoundComponents(childList);
463         return mainBldr;
464     }
465 
466     private PropositionDefinition.Builder makeOrCompoundProposition(PropositionDefinition.Builder... childPropBldrs) {
467         String propId = null;
468         String propTypeCode = PropositionType.COMPOUND.getCode();
469         String ruleId = null;
470         KrmsTypeDefinition type = this.krmsTypeRepositoryService.getTypeByName(KSKRMSServiceConstants.NAMESPACE_CODE,
471                 KSKRMSServiceConstants.PROPOSITION_TYPE_COMPOUND_OR);
472         String typeId = type.getId();
473         List<PropositionParameter.Builder> parameters = new ArrayList<PropositionParameter.Builder>();
474         PropositionDefinition.Builder mainBldr = PropositionDefinition.Builder.create(propId, propTypeCode, ruleId, typeId, parameters);
475         mainBldr.setCompoundOpCode(LogicalOperator.OR.getCode());
476         List<PropositionDefinition.Builder> childList = Arrays.asList(childPropBldrs);
477 //        System.out.println ("order for OR is:");
478 //        for (PropositionDefinition.Builder childBldr : childList) {
479 //            System.out.println ("order is " + childBldr);
480 //        }
481         mainBldr.setCompoundComponents(childList);
482         return mainBldr;
483     }
484 
485     @Test
486     public void testUpdateChangingPropositionConstantValuefrom1To2() {
487         AgendaDefinition agenda = createCheckBasicAgendaFor1OfCluSet23();
488 
489         AgendaItemDefinition firstItem = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
490         PropositionDefinition prop = firstItem.getRule().getProposition();
491         PropositionDefinition.Builder propBldr = PropositionDefinition.Builder.create(prop);
492         propBldr = this.updateNOfCluSetProposition(propBldr, 2);
493         this.updateCheckFirstItemSettingPropositionOnRule(agenda, propBldr);
494     }
495 
496     @Test
497     public void testUpdateCompletelyReplacingExistingPropositionCreatingOrphan() {
498         AgendaDefinition agenda = createCheckBasicAgendaFor1OfCluSet23();
499 
500         PropositionDefinition.Builder propBldr = this.constructFreeFormTextPropositionBulider("My first Text Value");
501         updateCheckFirstItemSettingPropositionOnRule(agenda, propBldr);
502     }
503 
504     @Test
505     public void testCreateMultiAgendaItems() {
506         //Create agenda
507         ContextDefinition context = this.findCreateContext();
508         AgendaDefinition agenda = createCheckEmptyAgenda(context);
509         AgendaItemDefinition firstItem = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
510         AgendaItemDefinition.Builder firstItemBldr = createMultiAgendaItems(firstItem);
511 
512         this.ruleManagementService.updateAgendaItem(firstItemBldr.build());
513         AgendaItemDefinition returnItem = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
514         checkMultiAgendaItem(firstItemBldr, returnItem);
515 
516     }
517 
518     @Test
519     public void testUpdateChangingTermParameters() {
520         //Create agenda
521         ContextDefinition context = this.findCreateContext();
522         AgendaDefinition agenda = createCheckEmptyAgenda(context);
523         AgendaItemDefinition firstItem = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
524         this.ruleManagementService.updateAgendaItem(createMultiAgendaItems(firstItem).build());
525 
526         firstItem = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
527         AgendaItemDefinition.Builder itemBuilder = AgendaItemDefinition.Builder.create(firstItem);
528         PropositionParameter.Builder propParameter = null;
529         for(PropositionParameter.Builder parameter : itemBuilder.getWhenTrue().getRule().getProposition().getParameters()){
530             if(parameter.getTermValue()!=null){
531                 propParameter = parameter;
532             }
533         }
534 
535         TermDefinition.Builder term = TermDefinition.Builder.create(propParameter.getTermValue());
536         for(TermParameterDefinition.Builder parameter : term.getParameters()){
537             parameter.setValue("The updated free form proposition");
538             break;
539         }
540         propParameter.setTermValue(term.build());
541 
542         this.ruleManagementService.updateAgendaItem(itemBuilder.build());
543         AgendaItemDefinition returnItem = this.ruleManagementService.getAgendaItem(itemBuilder.getId());
544         checkMultiAgendaItem(itemBuilder, returnItem);
545 
546     }
547 
548     private AgendaItemDefinition.Builder createMultiAgendaItems(AgendaItemDefinition firstItem){
549         //Add first item details.
550         PropositionDefinition.Builder firstPropBldr = this.constructFreeFormTextPropositionBulider("The first free form proposition");
551         RuleDefinition.Builder firstRuleBldr = this.constructEmptyRuleBuilder();
552         firstRuleBldr.setProposition(firstPropBldr);
553         AgendaItemDefinition.Builder firstItemBldr = AgendaItemDefinition.Builder.create(firstItem);
554         firstItemBldr.setRule(firstRuleBldr);
555 
556         //Add second item details.
557         PropositionDefinition.Builder secondPropBldr = this.constructFreeFormTextPropositionBulider("The second free form proposition");
558         RuleDefinition.Builder secondRuleBldr = this.constructEmptyRuleBuilder();
559         secondRuleBldr.setProposition(secondPropBldr);
560         AgendaItemDefinition.Builder secondItemBldr = AgendaItemDefinition.Builder.create(null, firstItem.getAgendaId());
561         secondItemBldr.setRule(secondRuleBldr);
562         firstItemBldr.setWhenTrue(secondItemBldr);
563 
564         return firstItemBldr;
565     }
566 
567     private void checkMultiAgendaItem(AgendaItemDefinition.Builder itemBuilder, AgendaItemDefinition item){
568         this.checkRule(itemBuilder.getRule(), item.getRule());
569         assertNotNull(item.getWhenTrue());
570         this.checkRule(itemBuilder.getWhenTrue().getRule(), item.getWhenTrue().getRule());
571     }
572 
573     private AgendaDefinition createCheckBasicAgendaFor1OfCluSet23() {
574         ContextDefinition context = this.findCreateContext();
575         AgendaDefinition agenda = createCheckEmptyAgenda(context);
576         agenda = updateCheckAgendaFirstItemAddingEmptyRule(agenda);
577         CluSetInfo cluSet = this.findCreateCluSet23();
578         PropositionDefinition.Builder propBldr = createNOfCluSetPropositionBuilder(1, cluSet);
579         agenda = updateCheckFirstItemSettingPropositionOnRule(agenda, propBldr);
580         return agenda;
581     }
582 
583     private CluSetInfo findCreateCluSet23() {
584         // create the cluset
585         CluInfo courseClu2 = this.getClu("COURSE2");
586         CluInfo courseClu3 = this.getClu("COURSE3");
587         List<String> versionIndIds = this.getVersionIndIds(courseClu2, courseClu3);
588         CluSetInfo cluSet = findCreateCluSet("cluSet23", "Courses 2 & 3", versionIndIds);
589         return cluSet;
590     }
591 
592     private CluSetInfo findCreateCluSet456() {
593         // create the cluset
594         CluInfo courseClu4 = this.getClu("COURSE4");
595         CluInfo courseClu5 = this.getClu("COURSE5");
596         CluInfo courseClu6 = this.getClu("COURSE6");
597         List<String> versionIndIds = this.getVersionIndIds(courseClu4, courseClu5, courseClu6);
598         CluSetInfo cluSet = findCreateCluSet("cluSet456", "Courses 4, 5 & 6", versionIndIds);
599         return cluSet;
600     }
601 
602     private ContextDefinition findCreateContext() {
603         // find/create the context corresponding to this context type.
604         ContextDefinition.Builder contextBldr = ContextDefinition.Builder.create(KSKRMSServiceConstants.NAMESPACE_CODE,
605                 KSKRMSServiceConstants.CONTEXT_COURSE_REQUIREMENTS);
606         contextBldr.setTypeId(KSKRMSServiceConstants.CONTEXT_TYPE_DEFAULT);
607         contextBldr.setDescription(KSKRMSServiceConstants.CONTEXT_COURSE_REQUIREMENTS);
608         contextBldr.setActive(true);
609         ContextDefinition context = this.ruleManagementService.findCreateContext(contextBldr.build());
610         this.checkContext(contextBldr, context);
611         return context;
612     }
613 
614     private void checkContext(ContextDefinition.Builder contextBldr, ContextDefinition context) {
615         assertNotNull(context);
616         assertNotNull(context.getId());
617         assertEquals(contextBldr.getName(), context.getName());
618         assertEquals(contextBldr.getNamespace(), context.getNamespace());
619         assertEquals(contextBldr.getTypeId(), context.getTypeId());
620         assertEquals(contextBldr.isActive(), context.isActive());
621     }
622 
623     private AgendaDefinition createCheckEmptyAgenda(ContextDefinition context) {
624         // find/create the context corresponding to this context type.
625         // create the agenda
626         KrmsTypeDefinition agendaType = this.krmsTypeRepositoryService.getTypeByName(KSKRMSServiceConstants.NAMESPACE_CODE,
627                 KSKRMSServiceConstants.AGENDA_TYPE_COURSE_ENROLLMENTELIGIBILITY);
628         assertNotNull(agendaType);
629         String id = null; // set by service when create is called
630         // For testing use a GUID instead of anchorClu.getId () so we always get a new one for testing
631         String name = UUIDHelper.genStringUUID();
632 //        String name = agendaType.getName() + " for " + anchorClu.getOfficialIdentifier().getCode() + " (" + anchorClu.getId() + ")";
633         String typeId = agendaType.getId();
634         String contextId = context.getId();
635         AgendaDefinition.Builder agendaBldr = AgendaDefinition.Builder.create(id, name, typeId, contextId);
636         agendaBldr.setActive(false);
637         AgendaDefinition agenda = this.ruleManagementService.findCreateAgenda(agendaBldr.build());
638         this.checkAgenda(agendaBldr, agenda);
639         return agenda;
640     }
641 
642     private void checkAgenda(AgendaDefinition.Builder agendaBldr, AgendaDefinition agenda) {
643         assertNotNull(agenda);
644         assertNotNull(agenda.getId());
645         assertEquals(agendaBldr.getName(), agenda.getName());
646         assertEquals(agendaBldr.getContextId(), agenda.getContextId());
647         assertEquals(agendaBldr.getTypeId(), agenda.getTypeId());
648         assertEquals(agendaBldr.isActive(), agenda.isActive());
649         if (agendaBldr.getFirstItemId() == null) {
650             assertNotNull(agenda.getFirstItemId());
651         } else {
652             assertEquals(agendaBldr.getFirstItemId(), agenda.getFirstItemId());
653         }
654     }
655 
656     private AgendaDefinition updateCheckAgendaFirstItemAddingEmptyRule(AgendaDefinition agenda) {
657         AgendaItemDefinition firstItem = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
658         assertNull(firstItem.getRule());
659         RuleDefinition.Builder ruleBldr = null;
660         ruleBldr = this.constructEmptyRuleBuilder();
661         AgendaItemDefinition.Builder itemBldr = AgendaItemDefinition.Builder.create(firstItem);
662         itemBldr.setRule(ruleBldr);
663         this.ruleManagementService.updateAgendaItem(itemBldr.build());
664         agenda = this.ruleManagementService.getAgenda(agenda.getId());
665         firstItem = this.ruleManagementService.getAgendaItem(firstItem.getId());
666         checkAgendaItem(agenda, itemBldr, firstItem);
667         return agenda;
668     }
669 
670     private void checkAgendaItem(AgendaDefinition agenda, AgendaItemDefinition.Builder itemBldr, AgendaItemDefinition item) {
671         assertNotNull(item);
672         assertNotNull(item.getId());
673         assertNotNull(agenda.getId(), item.getAgendaId());
674         if (item.getRule() == null) {
675             assertNull(item.getRuleId());
676         }
677         if (item.getRuleId() == null) {
678             assertNull(item.getRule());
679         }
680         if (item.getRule() != null) {
681             assertEquals(item.getRuleId(), item.getRule().getId());
682             checkRule(itemBldr.getRule(), item.getRule());
683         }
684     }
685 
686     private RuleDefinition.Builder constructEmptyRuleBuilder() {
687         // make rule
688         KrmsTypeDefinition ruleType = this.krmsTypeRepositoryService.getTypeByName(KSKRMSServiceConstants.NAMESPACE_CODE,
689                 KSKRMSServiceConstants.RULE_TYPE_COURSE_ACADEMICREADINESS_STUDENTELIGIBILITYPREREQ);
690         String ruleId = null; // sevice sets id
691 
692         // name has to be unique within namespace and max 100 characters.
693         // For testing use a GUID instead of anchorClu.getId () so we always get a new one for testing
694         String name = UUIDHelper.genStringUUID();
695 //        name = anchorClu.getOfficialIdentifier().getCode() + " " + ruleType.getName() + " (" + anchorClu.getId() + ")";
696         String namespace = KSKRMSServiceConstants.NAMESPACE_CODE;
697         String typeId = ruleType.getId();
698         String propId = null;
699         RuleDefinition.Builder ruleBldr = RuleDefinition.Builder.create(ruleId, name, namespace, typeId, propId);
700         ruleBldr.setActive(true);
701         return ruleBldr;
702     }
703 
704     private AgendaDefinition updateCheckFirstItemSettingPropositionOnRule(AgendaDefinition agenda, PropositionDefinition.Builder propBldr) {
705         AgendaItemDefinition firstItem = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
706         RuleDefinition.Builder ruleBldr = RuleDefinition.Builder.create(firstItem.getRule());
707         ruleBldr.setProposition(propBldr);
708 
709         AgendaItemDefinition.Builder itemBldr = AgendaItemDefinition.Builder.create(firstItem);
710         itemBldr.setRule(ruleBldr);
711         AgendaItemDefinition item2Update = itemBldr.build();
712         this.ruleManagementService.updateAgendaItem(item2Update);
713         agenda = this.ruleManagementService.getAgenda(agenda.getId());
714         firstItem = this.ruleManagementService.getAgendaItem(firstItem.getId());
715         this.checkAgendaItem(agenda, itemBldr, firstItem);
716         return agenda;
717     }
718 
719     private void checkRule(RuleDefinition.Builder ruleBldr, RuleDefinition rule) {
720         assertNotNull(rule.getId());
721         assertEquals(ruleBldr.getName(), rule.getName());
722         assertEquals(ruleBldr.getNamespace(), rule.getNamespace());
723         assertEquals(ruleBldr.getTypeId(), rule.getTypeId());
724         if (ruleBldr.getProposition() == null) {
725             assertNull(rule.getProposition());
726         } else {
727             this.checkProposition(rule.getId(), ruleBldr.getProposition(), rule.getProposition());
728         }
729     }
730 
731     private void checkProposition(String ruleId, PropositionDefinition.Builder propBldr, PropositionDefinition prop) {
732         assertEquals(ruleId, prop.getRuleId());
733 //        assertEquals(propBldr.getCompoundSequenceNumber(), prop.getCompoundSequenceNumber());
734         assertEquals(propBldr.getPropositionTypeCode(), prop.getPropositionTypeCode());
735         assertEquals(propBldr.getTypeId(), prop.getTypeId());
736         if (propBldr.getPropositionTypeCode().equals(PropositionType.SIMPLE.getCode())) {
737             this.checkSimpleProposition(propBldr, prop);
738         } else if (propBldr.getPropositionTypeCode().equals(PropositionType.COMPOUND.getCode())) {
739             this.checkCompoundProposition(ruleId, propBldr, prop);
740         } else {
741             fail("unknown proposition type " + propBldr.getPropositionTypeCode());
742         }
743     }
744 
745     private void checkCompoundProposition(String ruleId, PropositionDefinition.Builder propBldr, PropositionDefinition prop) {
746         assertEquals(PropositionType.COMPOUND.getCode(), propBldr.getPropositionTypeCode());
747         assertEquals(propBldr.getPropositionTypeCode(), prop.getPropositionTypeCode());
748 //        assertEquals(propBldr.getDescription(), prop.getDescription());
749         assertNotNull(propBldr.getCompoundOpCode());
750         assertEquals(propBldr.getCompoundOpCode(), prop.getCompoundOpCode());
751         // should not have parameters those are for simple propositions
752         assertTrue(propBldr.getParameters().isEmpty());
753         assertTrue(prop.getParameters().isEmpty());
754         assertEquals(propBldr.getCompoundComponents().size(), prop.getCompoundComponents().size());
755 
756         if (propBldr.getCompoundComponents().size() < 2) {
757             fail("there must be at least 2 compound components " + propBldr.getCompoundComponents().size());
758         }
759         for (int i = 0; i < propBldr.getCompoundComponents().size(); i++) {
760             PropositionDefinition childProp = prop.getCompoundComponents().get(i);
761             PropositionDefinition.Builder childPropBldr = propBldr.getCompoundComponents().get(i);
762             this.checkProposition(ruleId, childPropBldr, childProp);
763         }
764     }
765 
766     private void checkSimpleProposition(PropositionDefinition.Builder propBldr, PropositionDefinition prop) {
767 
768         assertEquals(PropositionType.SIMPLE.getCode(), propBldr.getPropositionTypeCode());
769         assertEquals(propBldr.getPropositionTypeCode(), prop.getPropositionTypeCode());
770         // should not have compound stuff those are for compound propositions
771         assertNull(propBldr.getCompoundOpCode());
772         assertNull(prop.getCompoundOpCode());
773         if (propBldr.getCompoundComponents() != null) {
774             assertTrue(propBldr.getCompoundComponents().isEmpty());
775             assertTrue(prop.getCompoundComponents().isEmpty());
776         }
777         assertEquals(propBldr.getParameters().size(),
778                 prop.getParameters().size());
779         for (int i = 0; i < propBldr.getParameters().size(); i++) {
780             PropositionParameter.Builder propParamBldr = propBldr.getParameters().get(0);
781             PropositionParameter propParam = prop.getParameters().get(0);
782 
783             assertNotNull(propParam.getId());
784             assertNotNull(propParamBldr.getParameterType());
785             assertNotNull(propParamBldr.getSequenceNumber());
786             assertEquals(propParamBldr.getSequenceNumber(),
787                     propParam.getSequenceNumber());
788             assertEquals(propParamBldr.getParameterType(),
789                     propParam.getParameterType());
790             assertEquals(prop.getId(), propParam.getPropId());
791             if (propParamBldr.getParameterType().equals(PropositionParameterType.TERM.getCode())) {
792                 this.checkTerm(propParam.getValue(), propParamBldr.getTermValue(), propParam.getTermValue());
793             } else {
794                 assertEquals(propParamBldr.getValue(), propParam.getValue());
795                 assertNull(propParam.getTermValue());
796             }
797         }
798     }
799 
800     private void checkTerm(String value, TermDefinition termBldr, TermDefinition term) {
801         assertNotNull(termBldr);
802         assertNotNull(term);
803         assertNotNull(term.getId());
804         assertEquals(value, term.getId());
805         assertNotNull(termBldr.getSpecification());
806         assertNotNull(term.getSpecification());
807         assertEquals(termBldr.getSpecification().getName(),
808                 term.getSpecification().getName());
809         assertEquals(termBldr.getSpecification().getNamespace(),
810                 term.getSpecification().getNamespace());
811         assertEquals(termBldr.getParameters().size(),
812                 term.getParameters().size());
813         for (int i = 0; i < term.getParameters().size(); i++) {
814             TermParameterDefinition termParamBldr = termBldr.getParameters().get(i);
815             TermParameterDefinition termParam = term.getParameters().get(i);
816             this.checkTermParam(term.getId(), termParamBldr, termParam);
817         }
818     }
819 
820     private void checkTermParam(String termId, TermParameterDefinition termParamBldr, TermParameterDefinition termParam) {
821         assertNotNull(termParam.getId());
822         assertEquals(termId, termParam.getTermId());
823         assertNotNull(termParam.getName());
824         assertEquals(termParamBldr.getName(), termParam.getName());
825         assertEquals(termParamBldr.getValue(), termParam.getValue());
826     }
827     private static final String N_OF_CLU_SET_TERM_NAME = "NumberOfCompletedCourses";
828     private static final String N_OF_CLU_SET_OPERATOR = "<=";
829 
830     private PropositionDefinition.Builder createNOfCluSetPropositionBuilder(int n, CluSetInfo cluSet) {
831 
832         // create all the parameters
833         List<PropositionParameter.Builder> parameters = new ArrayList<PropositionParameter.Builder>();
834         String constantValue = "" + n;
835 
836         // first the parameter to the parameter! (actually the term parameter to the proposition parameter that is a term!
837         List<TermParameterDefinition.Builder> termParameters = new ArrayList<TermParameterDefinition.Builder>();
838         String id = null; //set by service
839         String termId = null;
840         String name = "CourseSetId";
841         String value = cluSet.getId(); // this was created when the cluSet was built
842         TermParameterDefinition.Builder termParamBldr = TermParameterDefinition.Builder.create(id, termId, name, value);
843         termParameters.add(termParamBldr);
844 
845         id = null; // set by service
846         TermSpecificationDefinition termSpec =
847                 this.termRepositoryService.getTermSpecificationByNameAndNamespace(N_OF_CLU_SET_TERM_NAME,
848                         KSKRMSServiceConstants.NAMESPACE_CODE);
849         assertNotNull(termSpec);
850         assertEquals(N_OF_CLU_SET_TERM_NAME, termSpec.getName());
851         TermSpecificationDefinition.Builder termSpecBldr = TermSpecificationDefinition.Builder.create(termSpec);
852         String description = termSpec.getName() + " for " + cluSet.getId();
853         TermDefinition.Builder termBldr = TermDefinition.Builder.create(id, termSpecBldr, termParameters);
854         termBldr.setDescription(description);
855 
856 
857         // do the term parameter first
858         id = null; // should be set by service
859         String propId = null; // should also be set by the service when the create on the proposition happens
860         value = null;  // set by service
861         String parameterType = PropositionParameterType.TERM.getCode();
862         Integer sequenceNumber = 1;
863         PropositionParameter.Builder propParamBldr = PropositionParameter.Builder.create(id, propId, value, parameterType, sequenceNumber);
864         propParamBldr.setTermValue(termBldr.build());
865         parameters.add(propParamBldr);
866 
867 
868         // do the constant value next
869         id = null; // should be set by service
870         propId = null; // should also be set by the service when the create on the proposition happens
871         value = constantValue;
872         parameterType = PropositionParameterType.CONSTANT.getCode();
873         sequenceNumber = 2;
874         propParamBldr = PropositionParameter.Builder.create(id, propId, value, parameterType, sequenceNumber);
875         parameters.add(propParamBldr);
876 
877         // do the operator 
878         id = null; // should be set by service
879         propId = null; // should also be set by the service when the create on the proposition happens
880         value = N_OF_CLU_SET_OPERATOR;
881         parameterType = PropositionParameterType.OPERATOR.getCode();
882         sequenceNumber = 3;
883         propParamBldr = PropositionParameter.Builder.create(id, propId, value, parameterType, sequenceNumber);
884         parameters.add(propParamBldr);
885 
886         propId = null; // should be null until assigned by service
887         String propTypeCode = PropositionType.SIMPLE.getCode();
888         String ruleId = null;  // assigned by service
889         KrmsTypeDefinition propType = this.krmsTypeRepositoryService.getTypeByName(KSKRMSServiceConstants.NAMESPACE_CODE, KSKRMSServiceConstants.PROPOSITION_TYPE_COURSE_COURSESET_COMPLETED_NOF);
890         String typeId = propType.getId();
891         PropositionDefinition.Builder propBldr = PropositionDefinition.Builder.create(propId, propTypeCode, ruleId, typeId, parameters);
892 //        propBldr.setDescription(propType.getName());
893         return propBldr;
894     }
895 
896     private PropositionDefinition.Builder updateNOfCluSetProposition(PropositionDefinition.Builder propBldr, int n) {
897         PropositionParameter.Builder propParamBldr = propBldr.getParameters().get(1);
898         propParamBldr.setValue("" + n);
899         return propBldr;
900     }
901     private static final String FREE_FORM_TEXT_TERM_NAME = "FreeFormText";
902     private static final String FREE_FORM_TEXT_TERM_PARAM_NAME = "Text";
903     private static final String FREE_FORM_TEXT_CONSTANT_VALUE = "true";
904     private static final String FREE_FORM_TEXT_OPERATOR = "=";
905 
906     private PropositionDefinition.Builder constructFreeFormTextPropositionBulider(String myText) {
907         // create all the parameters
908         List<PropositionParameter.Builder> parameters = new ArrayList<PropositionParameter.Builder>();
909 
910 
911         // first the parameter to the parameter! (actually the term parameter to the proposition parameter that is a term!
912         List<TermParameterDefinition.Builder> termParameters = new ArrayList<TermParameterDefinition.Builder>();
913         String id = null; //set by service
914         String termId = null;
915         TermParameterDefinition.Builder termParamBldr = TermParameterDefinition.Builder.create(id, termId, FREE_FORM_TEXT_TERM_PARAM_NAME, myText);
916         termParameters.add(termParamBldr);
917 
918         id = null; // set by service
919         TermSpecificationDefinition termSpec =
920                 this.termRepositoryService.getTermSpecificationByNameAndNamespace(FREE_FORM_TEXT_TERM_NAME,
921                         KSKRMSServiceConstants.NAMESPACE_CODE);
922         assertNotNull(termSpec);
923         assertEquals(FREE_FORM_TEXT_TERM_NAME, termSpec.getName());
924         TermSpecificationDefinition.Builder termSpecBldr = TermSpecificationDefinition.Builder.create(termSpec);
925         String description = termSpec.getName();
926         TermDefinition.Builder termBldr = TermDefinition.Builder.create(id, termSpecBldr, termParameters);
927         termBldr.setDescription(description);
928 
929         // do the term parameter first
930         id = null; // should be set by service
931         String propId = null; // should also be set by the service when the create on the proposition happens
932         String value = null;  // set by service
933         String parameterType = PropositionParameterType.TERM.getCode();
934         Integer sequenceNumber = 1;
935         PropositionParameter.Builder propParamBldr = PropositionParameter.Builder.create(id,
936                 propId, value, parameterType, sequenceNumber);
937         propParamBldr.setTermValue(termBldr.build());
938         parameters.add(propParamBldr);
939 
940 
941         // do the constant value next
942         id = null; // should be set by service
943         propId = null; // should also be set by the service when the create on the proposition happens
944         value = FREE_FORM_TEXT_CONSTANT_VALUE;
945         parameterType = PropositionParameterType.CONSTANT.getCode();
946         sequenceNumber = 2;
947         propParamBldr = PropositionParameter.Builder.create(id, propId, value, parameterType, sequenceNumber);
948         parameters.add(propParamBldr);
949 
950         // do the operator 
951         id = null; // should be set by service
952         propId = null; // should also be set by the service when the create on the proposition happens
953         value = FREE_FORM_TEXT_OPERATOR;
954         parameterType = PropositionParameterType.OPERATOR.getCode();
955         sequenceNumber = 3;
956         propParamBldr = PropositionParameter.Builder.create(id, propId, value, parameterType, sequenceNumber);
957         parameters.add(propParamBldr);
958 
959         propId = null; // should be null until assigned by service
960         String propTypeCode = PropositionType.SIMPLE.getCode();
961         String ruleId = null;  // assigned by service
962         KrmsTypeDefinition propType = this.krmsTypeRepositoryService.getTypeByName(KSKRMSServiceConstants.NAMESPACE_CODE, KSKRMSServiceConstants.PROPOSITION_TYPE_FREEFORM_TEXT);
963         String typeId = propType.getId();
964         PropositionDefinition.Builder propBldr = PropositionDefinition.Builder.create(propId, propTypeCode, ruleId, typeId, parameters);
965 //        propBldr.setDescription(propType.getName());
966         return propBldr;
967     }
968 
969     private CluSetInfo findCreateCluSet(String id, String name, List<String> versionIndIds) {
970         CluSetInfo cluSetInfo;
971         try {
972             cluSetInfo = this.cluService.getCluSet(id, contextInfo);
973             return cluSetInfo;
974         } catch (DoesNotExistException ex) {
975             // does not exist so create
976         } catch (Exception ex) {
977             throw new IllegalArgumentException(ex);
978         }
979         cluSetInfo = new CluSetInfo();
980         cluSetInfo.setId(id);
981         cluSetInfo.setTypeKey(CluServiceConstants.CLUSET_TYPE_CREDIT_COURSE);
982         cluSetInfo.setStateKey("Active");
983         cluSetInfo.setName(name);
984         cluSetInfo.setEffectiveDate(new Date());
985         cluSetInfo.setIsReferenceable(Boolean.TRUE);
986         cluSetInfo.setIsReusable(Boolean.FALSE);
987         cluSetInfo.setCluIds(versionIndIds);
988         try {
989             cluSetInfo = this.cluService.createCluSet(cluSetInfo.getTypeKey(), cluSetInfo, contextInfo);
990         } catch (Exception ex) {
991             throw new IllegalArgumentException(ex);
992         }
993         return cluSetInfo;
994     }
995 
996     private List<String> getVersionIndIds(CluInfo... clus) {
997         List<String> list = new ArrayList<String>();
998         for (CluInfo clu : clus) {
999             list.add(clu.getVersion().getVersionIndId());
1000         }
1001         return list;
1002     }
1003 
1004     private CluInfo getClu(String id) {
1005         try {
1006             return this.cluService.getClu(id, contextInfo);
1007         } catch (Exception ex) {
1008             throw new RuntimeException(ex);
1009         }
1010     }
1011     // cache
1012     private transient Map<String, NaturalLanguageUsage> name2NaturalLanguageUsageCache = null;
1013 
1014     private NaturalLanguageUsage getNaturalLanguageUsage(String name, String namespace) {
1015         if (name2NaturalLanguageUsageCache == null) {
1016             name2NaturalLanguageUsageCache = new LinkedHashMap<String, NaturalLanguageUsage>();
1017         }
1018         String key = namespace + ":" + name;
1019         NaturalLanguageUsage usage = name2NaturalLanguageUsageCache.get(key);
1020         if (usage != null) {
1021             return usage;
1022         }
1023         // get the usage
1024         usage = this.ruleManagementService.getNaturalLanguageUsageByNameAndNamespace(name, namespace);
1025         assertNotNull(usage);
1026         assertEquals(name, usage.getName());
1027         assertEquals(namespace, usage.getNamespace());
1028         name2NaturalLanguageUsageCache.put(key, usage);
1029         return usage;
1030     }
1031 
1032     private NaturalLanguageUsage getTypeDescriptionUsage() {
1033         return this.getNaturalLanguageUsage(KSKRMSServiceConstants.KRMS_NL_TYPE_DESCRIPTION, KSKRMSServiceConstants.NAMESPACE_CODE);
1034     }
1035 
1036     private NaturalLanguageUsage getRuleEditUsage() {
1037         return this.getNaturalLanguageUsage(KSKRMSServiceConstants.KRMS_NL_RULE_EDIT, KSKRMSServiceConstants.NAMESPACE_CODE);
1038     }
1039 
1040     private NaturalLanguageUsage getPreviewUsage() {
1041         return this.getNaturalLanguageUsage(KSKRMSServiceConstants.KRMS_NL_PREVIEW, KSKRMSServiceConstants.NAMESPACE_CODE);
1042     }
1043 
1044     private KrmsTypeDefinition simulateGettingCourseAgendaType() {
1045         KrmsTypeDefinition type = this.krmsTypeRepositoryService.getTypeByName(KSKRMSServiceConstants.NAMESPACE_CODE, KSKRMSServiceConstants.AGENDA_TYPE_COURSE);
1046         assertNotNull(type);
1047         assertEquals(KSKRMSServiceConstants.AGENDA_TYPE_COURSE, type.getName());
1048         assertEquals(KSKRMSServiceConstants.NAMESPACE_CODE, type.getNamespace());
1049         return type;
1050     }
1051 
1052     private KrmsTypeDefinition simulateUserChoosingType(String title, List<KrmsTypeDefinition> types, String languageCode, int defaultIndex) {
1053         System.out.println(title);
1054         this.displayScreenDescriptions(types, languageCode);
1055         System.out.print("==> Choose: ");
1056         KrmsTypeDefinition selected = types.get(defaultIndex);
1057         System.out.println(selected.getName());
1058         return selected;
1059     }
1060 
1061     private void displayScreenDescriptions(List<KrmsTypeDefinition> types, String languageCode) {
1062         for (KrmsTypeDefinition type : types) {
1063             System.out.println(this.getScreenDescription(type.getId(), languageCode));
1064         }
1065     }
1066 
1067     private String getScreenDescription(String typeId, String languageCode) {
1068         // check there is a corresponding template so we can display on the screen what kind of rule this is
1069         NaturalLanguageTemplate template =
1070                 this.ruleManagementService.findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(languageCode,
1071                 typeId,
1072                 this.getTypeDescriptionUsage().getId());
1073         if (template == null) {
1074             System.out.println("could not find template for " + typeId + " with language " + languageCode + " and for type description usage");
1075         }
1076         assertNotNull(template);
1077         assertEquals(languageCode, template.getLanguageCode());
1078         assertEquals(typeId, template.getTypeId());
1079         assertEquals(getTypeDescriptionUsage().getId(), template.getNaturalLanguageUsageId());
1080         return template.getTemplate();
1081     }
1082 
1083     private NaturalLanguageTemplate getRuleEditUsageNaturalLanguageTemplate(String typeId, String languageCode) {
1084         // check there is a corresponding template so we can display on the screen what kind of rule this is
1085         NaturalLanguageTemplate template =
1086                 this.ruleManagementService.findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(languageCode,
1087                 typeId,
1088                 this.getRuleEditUsage().getId());
1089         if (template == null) {
1090             System.out.println("could not find template for " + typeId + " with language " + languageCode + " and for rule edit usage");
1091         }
1092         assertNotNull(template);
1093         assertEquals(languageCode, template.getLanguageCode());
1094         assertEquals(typeId, template.getTypeId());
1095         assertEquals(getRuleEditUsage().getId(), template.getNaturalLanguageUsageId());
1096         return template;
1097     }
1098 
1099     private void checkTypeNamesAnyOrder(Set<String> expected, List<KrmsTypeDefinition> types) {
1100         List<String> unexpected = new ArrayList<String>();
1101         for (KrmsTypeDefinition type : types) {
1102             if (!expected.remove(type.getName())) {
1103                 unexpected.add(type.getName());
1104             }
1105         }
1106         if (!expected.isEmpty() || !unexpected.isEmpty()) {
1107             fail(expected.size() + " types expected that were not found " + expected
1108                     + " and "
1109                     + unexpected.size() + " types were found but not expected " + unexpected);
1110         }
1111     }
1112 
1113     private void checkTypeNamesOrdered(Set<String> expected, List<KrmsTypeDefinition> types) {
1114         List<String> expectedOrdered = new ArrayList(expected);
1115         this.checkTypeNamesAnyOrder(expected, types);
1116         for (int i = 0; i < types.size(); i++) {
1117             if (!expectedOrdered.get(i).equals(types.get(i).getName())) {
1118                 fail("Expected " + i + "th position to have " + expectedOrdered.get(i) + " but found " + types.get(i).getName());
1119             }
1120         }
1121     }
1122 
1123     private CluInfo getCurrentCluInfoByVersionIndId(String id, ContextInfo contextInfo) {
1124         VersionDisplayInfo versionDisplayInfo = null;
1125         try {
1126             versionDisplayInfo = this.cluService.getCurrentVersion(CluServiceConstants.CLU_NAMESPACE_URI, id, contextInfo);
1127         } catch (Exception ex) {
1128             throw new IllegalArgumentException("Unexpected", ex);
1129         }
1130         try {
1131             return this.cluService.getClu(versionDisplayInfo.getId(), contextInfo);
1132         } catch (Exception ex) {
1133             throw new IllegalArgumentException("Unexpected", ex);
1134         }
1135     }
1136 
1137     // commented out this test because it is brittle and what gets returned changes as the configuration changes
1138 //    @Test
1139     public void testBasicTypeConfiguration() {
1140 
1141         List<KrmsTypeDefinition> types = null;
1142         Set<String> expected = null;
1143         String languageCode = KSKRMSServiceConstants.LANGUAGE_CODE_ENGLISH;
1144         // check that we can get all the different context types
1145         types = this.krmsTypeRepositoryService.findAllContextTypes();
1146         expected = new LinkedHashSet<String>();
1147         // TODO: find out why all the context's were removed!
1148 //        expected.add(KsKrmsConstants.CONTEXT_TYPE_COURSE);
1149 //        expected.add(KsKrmsConstants.CONTEXT_TYPE_PROGRAM);
1150 //        expected.add(KsKrmsConstants.CONTEXT_TYPE_COURSE_OFFERING);
1151         this.checkTypeNamesAnyOrder(expected, types);
1152 
1153         // Typically the user does not actually select the context but it is
1154         // hardwired into the program, so the "context" is taken from where 
1155         // we are within the application, i.e. are we on the course requisites screen?
1156         System.out.println("Please choose which context of rules that you want to work on:");
1157         for (KrmsTypeDefinition type : types) {
1158             System.out.println("     " + this.getScreenDescription(type.getId(), languageCode));
1159         }
1160 //        System.out.print("==> Choose: ");
1161 //        String selectedId = this.simulateUserChoosingContextTypeId();
1162 //        System.out.println(selectedId);
1163 //        KrmsTypeDefinition selectedContextType = this.krmsTypeRepositoryService.getTypeById(selectedId);
1164 //        description = this.getScreenDescription(selectedContextType.getId(), languageCode);
1165 //        System.out.println("Editing Rules for Context: " + description);
1166 
1167 
1168         // 
1169         KrmsTypeDefinition courseAgendaType = this.simulateGettingCourseAgendaType();
1170         assertNotNull(courseAgendaType);
1171 
1172         // Get all the agenda types for this course context type
1173 
1174         types = this.krmsTypeRepositoryService.findAgendaTypesForAgendaType(courseAgendaType.getId());
1175         expected = new LinkedHashSet<String>();
1176         expected.add(KSKRMSServiceConstants.AGENDA_TYPE_COURSE_ENROLLMENTELIGIBILITY);
1177         expected.add(KSKRMSServiceConstants.AGENDA_TYPE_COURSE_CREDITCONSTRAINTS);
1178         this.checkTypeNamesOrdered(expected, types);
1179 
1180         String title = "Please choose which type of rule you want to work on:";
1181         int defaultIndex = 0;
1182         KrmsTypeDefinition courseEligAgendaType = this.simulateUserChoosingType(title, types, languageCode, defaultIndex);
1183 
1184         // Get all the agenda types for the main agenda type
1185         // Right now we don't do this we just have rule types so this should return an empty list
1186         types = this.krmsTypeRepositoryService.findAgendaTypesForAgendaType(courseEligAgendaType.getId());
1187         expected = new LinkedHashSet<String>();
1188         this.checkTypeNamesOrdered(expected, types);
1189 
1190         // Get all the RULE types for the main agenda type
1191         types = this.krmsTypeRepositoryService.findRuleTypesForAgendaType(courseEligAgendaType.getId());
1192         expected = new LinkedHashSet<String>();
1193         expected.add(KSKRMSServiceConstants.RULE_TYPE_COURSE_ACADEMICREADINESS_STUDENTELIGIBILITYPREREQ);
1194         expected.add(KSKRMSServiceConstants.RULE_TYPE_COURSE_ACADEMICREADINESS_COREQ);
1195         expected.add(KSKRMSServiceConstants.RULE_TYPE_COURSE_RECOMMENDEDPREPARATION);
1196         expected.add(KSKRMSServiceConstants.RULE_TYPE_COURSE_ACADEMICREADINESS_ANTIREQ);
1197         this.checkTypeNamesOrdered(expected, types);
1198 
1199         title = "Please choose which type of rule you want to work on:";
1200         defaultIndex = 0;
1201         KrmsTypeDefinition eligPrereqRuleType = this.simulateUserChoosingType(title, types, languageCode, defaultIndex);
1202 
1203         // Get all the Proposition types for the rule type
1204         types = this.krmsTypeRepositoryService.findPropositionTypesForRuleType(eligPrereqRuleType.getId());
1205         expected = new LinkedHashSet<String>();
1206         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_FREEFORM_TEXT);
1207         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_SUCCESS_COMPL_COURSE);
1208         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_CUMULATIVE_GPA_MIN);
1209         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_ADMITTED_TO_PROGRAM);
1210         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_SUCCESS_CREDIT_COURSESET_COMPLETED_NOF);
1211         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_SUCCESS_CREDITS_COURSESET_COMPLETED_NOF_ORG);
1212         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_SUCCESS_COURSE_COURSESET_COMPLETED_ALL);
1213         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_SUCCESS_COURSE_COURSESET_COMPLETED_NOF);
1214         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_COURSE_COURSESET_GPA_MIN);
1215         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_COURSE_COURSESET_GRADE_MIN);
1216         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_COURSE_COURSESET_NOF_GRADE_MIN);
1217 //        expected.add(KsKrmsConstants.PROPOSITION_TYPE_COURSE_COURSESET_GRADE_MAX);
1218         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_ADMITTED_TO_PROGRAM_CAMPUS);
1219 //        expected.add(KsKrmsConstants.PROPOSITION_TYPE_NOTADMITTED_TO_PROGRAM);
1220         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_PERMISSION_INSTRUCTOR_REQUIRED);
1221         expected.add(KSKRMSServiceConstants.PROPOSITION_TYPE_PERMISSION_ADMIN_ORG);
1222 //        expected.add(KsKrmsConstants.PROPOSITION_TYPE_COURSE_TEST_SCORE_MIN);
1223 //        expected.add(KsKrmsConstants.PROPOSITION_TYPE_TEST_SCORE_BETWEEN_VALUES);
1224 //        expected.add(KsKrmsConstants.PROPOSITION_TYPE_TEST_SCORE);
1225         this.checkTypeNamesOrdered(expected, types);
1226 
1227         title = "Please choose which type of rule you want to work on:";
1228         defaultIndex = 7;
1229         KrmsTypeDefinition nOfCoursesPropositionType = this.simulateUserChoosingType(title, types, languageCode, defaultIndex);
1230         NaturalLanguageTemplate nlTemplate = this.getRuleEditUsageNaturalLanguageTemplate(nOfCoursesPropositionType.getId(), languageCode);
1231         assertNotNull(nlTemplate);
1232         assertEquals("#if($intValue == 1 && $courseCluSet.getCluList().size() == 1)Must have successfully completed $courseCluSet.getCluSetAsCode()#{else}Must have successfully completed a minimum of $intValue $NLHelper.getProperGrammar($intValue, \"course\") from $courseCluSet.getCluSetAsCode()#end", nlTemplate.getTemplate());
1233 
1234 //                <entry key="kuali.krms.proposition.type.success.course.courseset.completed.nof">
1235 //                    <bean parent="TemplateInfo-parent"
1236 //                          p:termSpecName="NumberOfCompletedCourses" p:operator="&lt;=" p:value="n">
1237 //                        <property name="componentId" value="KRMS-MultiCourse-Section"/>
1238 //                        <property name="constantComponentId" value="KRMS-NumberOfCourses-ConstantValue"/>
1239 //                        <property name="componentBuilderClass" value="org.kuali.student.lum.lu.ui.krms.builder.MultiCourseComponentBuilder"/>
1240 //                    </bean>
1241 //                </entry>
1242 
1243 
1244         // Get all the parameter types for the proposition type
1245         types = this.krmsTypeRepositoryService.findPropositionParameterTypesForPropositionType(nOfCoursesPropositionType.getId());
1246         expected = new LinkedHashSet<String>();
1247         this.checkTypeNamesOrdered(expected, types);
1248 
1249 //        TermResolverDefinition termResolver =
1250 //                this.termRepositoryService.getTermResolverByNameAndNamespace(termName,
1251 //                KsKrmsConstants.NAMESPACE_CODE);
1252 //        assertNotNull(termResolver);
1253 //        assertEquals (termName, termResolver.getName());
1254     }
1255 
1256     @Test
1257     public void testTranslateNaturalLanguageForProposition() {
1258         ContextDefinition context = this.findCreateContext();
1259         AgendaDefinition agenda = createCheckEmptyAgenda(context);
1260         agenda = updateCheckAgendaFirstItemAddingEmptyRule(agenda);
1261 
1262         PropositionDefinition.Builder propBldr1 = this.constructFreeFormTextPropositionBulider("My first Text Value");
1263         CluSetInfo cluSet = this.findCreateCluSet23();
1264         PropositionDefinition.Builder propBldr2 = createNOfCluSetPropositionBuilder(1, cluSet);
1265         cluSet = this.findCreateCluSet456();
1266         PropositionDefinition.Builder propBldr3 = createNOfCluSetPropositionBuilder(2, cluSet);
1267 
1268         PropositionDefinition.Builder andPropBldr = this.makeAndCompoundProposition(propBldr2, propBldr3);
1269         PropositionDefinition.Builder orPropBldr = this.makeOrCompoundProposition(propBldr1, andPropBldr);
1270 
1271         AgendaItemDefinition firstItem = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
1272         RuleDefinition.Builder ruleBldr = RuleDefinition.Builder.create(firstItem.getRule());
1273         ruleBldr.setProposition(orPropBldr);
1274 
1275         AgendaItemDefinition.Builder itemBldr = AgendaItemDefinition.Builder.create(firstItem);
1276         itemBldr.setRule(ruleBldr);
1277         AgendaItemDefinition item2Update = itemBldr.build();
1278         this.ruleManagementService.updateAgendaItem(item2Update);
1279         agenda = this.ruleManagementService.getAgenda(agenda.getId());
1280         firstItem = this.ruleManagementService.getAgendaItem(firstItem.getId());
1281 
1282         List<NaturalLanguageUsage> usages = this.ruleManagementService.getNaturalLanguageUsagesByNamespace(KSKRMSServiceConstants.NAMESPACE_CODE);
1283 
1284         System.out.println(this.ruleManagementService.translateNaturalLanguageForObject("KS-KRMS-NL-USAGE-1000", "agenda", agenda.getId(), "en"));
1285         System.out.println(this.ruleManagementService.translateNaturalLanguageForObject("KS-KRMS-NL-USAGE-1000", "rule", firstItem.getRule().getId(), "en"));
1286         System.out.println(this.ruleManagementService.translateNaturalLanguageForObject("KS-KRMS-NL-USAGE-1000", "proposition", firstItem.getRule().getProposition().getId(), "en"));
1287 
1288     }
1289 }