001/*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005package org.kuali.rice.krms.impl.repository;
006
007import java.util.ArrayList;
008import java.util.Date;
009import java.util.LinkedHashMap;
010import java.util.LinkedHashSet;
011import java.util.List;
012import java.util.Map;
013import java.util.Set;
014import javax.xml.namespace.QName;
015import org.junit.After;
016import org.junit.AfterClass;
017import static org.junit.Assert.*;
018import org.junit.Before;
019import org.junit.BeforeClass;
020import org.junit.Test;
021import org.junit.Ignore;
022import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
023import org.kuali.rice.krms.api.repository.LogicalOperator;
024import org.kuali.rice.krms.api.repository.RuleManagementService;
025import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
026import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
027import org.kuali.rice.krms.api.repository.context.ContextDefinition;
028import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
029import org.kuali.rice.krms.api.repository.language.NaturalLanguageUsage;
030import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
031import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
032import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType;
033import org.kuali.rice.krms.api.repository.proposition.PropositionType;
034import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
035import org.kuali.rice.krms.api.repository.term.TermDefinition;
036import org.kuali.rice.krms.api.repository.term.TermParameterDefinition;
037import org.kuali.rice.krms.api.repository.term.TermRepositoryService;
038import org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition;
039import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
040import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService;
041import org.kuali.rice.krms.impl.repository.mock.KrmsConfigurationLoader;
042import org.kuali.student.common.util.UUIDHelper;
043import org.kuali.student.r2.common.dto.ContextInfo;
044import org.kuali.student.r2.common.exceptions.*;
045import org.kuali.student.r2.core.constants.KSKRMSServiceConstants;
046import org.kuali.student.r2.core.process.krms.KSKRMSTestCase;
047import org.kuali.student.r2.core.versionmanagement.dto.VersionDisplayInfo;
048import org.kuali.student.r2.lum.clu.dto.CluInfo;
049import org.kuali.student.r2.lum.clu.dto.CluSetInfo;
050import org.kuali.student.r2.lum.clu.service.CluService;
051import org.kuali.student.r2.lum.lu.service.impl.CluDataLoader;
052import org.kuali.student.r2.lum.lu.service.impl.CluServiceMockImpl;
053import org.kuali.student.r2.lum.util.constants.CluServiceConstants;
054import java.util.Arrays;
055import org.kuali.rice.krms.api.repository.reference.ReferenceObjectBinding;
056import org.kuali.rice.krms.impl.util.KrmsRuleManagementCopyMethods;
057import org.kuali.rice.krms.impl.util.KrmsRuleManagementCopyMethodsImpl;
058
059/**
060 *
061 * @author nwright
062 */
063// TODO: KSENROLL-7265  remove ignore per larry's request that all @Ignore's have an associated jira 
064@Ignore
065public class RuleManagementServiceImplTest extends KSKRMSTestCase {
066
067    private KrmsTypeRepositoryService krmsTypeRepositoryService = null;
068    private RuleManagementService ruleManagementService = null;
069    private TermRepositoryService termRepositoryService = null;
070    private CluService cluService = null;
071    private KrmsRuleManagementCopyMethods krmsRuleManagementCopyMethods = null;
072
073    @BeforeClass
074    public static void setUpClass() {
075    }
076
077    @AfterClass
078    public static void tearDownClass() {
079    }
080    private ContextInfo contextInfo;
081
082    @Before
083    public void setUp() throws Exception {
084        super.setUp();
085        contextInfo = new ContextInfo();
086        contextInfo.setPrincipalId("TESTUSER");
087        contextInfo.setCurrentDate(new Date());
088
089        this.krmsTypeRepositoryService = (KrmsTypeRepositoryService) GlobalResourceLoader.getService(QName.valueOf("krmsTypeRepositoryService"));
090        this.termRepositoryService = (TermRepositoryService) GlobalResourceLoader.getService(QName.valueOf("termRepositoryService"));
091        this.ruleManagementService = (RuleManagementService) GlobalResourceLoader.getService(QName.valueOf("ruleManagementService"));
092        KrmsRuleManagementCopyMethodsImpl copyImpl = new KrmsRuleManagementCopyMethodsImpl();
093//        copyImpl.setKrmsTypeRepositoryService(krmsTypeRepositoryService);
094        copyImpl.setRuleManagementService(ruleManagementService);
095        this.krmsRuleManagementCopyMethods = copyImpl;
096        KrmsConfigurationLoader loader = new KrmsConfigurationLoader();
097//        loader.setKrmsTypeRepositoryService(this.krmsTypeRepositoryService);
098//        loader.setRuleManagementService(this.ruleManagementService);
099//        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}