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