001/**
002 * Copyright 2005-2013 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krms.impl.repository;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.criteria.GenericQueryResults;
020import org.kuali.rice.core.api.criteria.Predicate;
021import org.kuali.rice.core.api.criteria.QueryByCriteria;
022import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
023import org.kuali.rice.krad.service.BusinessObjectService;
024import org.kuali.rice.krms.api.repository.NaturalLanguage;
025import org.kuali.rice.krms.api.repository.RuleManagementService;
026import org.kuali.rice.krms.api.repository.TranslateBusinessMethods;
027import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
028import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
029import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
030import org.kuali.rice.krms.api.repository.language.NaturalLanguageUsage;
031import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
032import org.kuali.rice.krms.api.repository.reference.ReferenceObjectBinding;
033import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
034
035import java.util.ArrayList;
036import java.util.Collections;
037import java.util.HashMap;
038import java.util.LinkedHashSet;
039import java.util.LinkedList;
040import java.util.List;
041import java.util.Map;
042import java.util.Set;
043
044import org.kuali.rice.krad.service.KRADServiceLocator;
045import org.kuali.rice.krad.service.SequenceAccessorService;
046import org.kuali.rice.krms.api.repository.NaturalLanguageTree;
047import org.kuali.rice.krms.api.repository.action.ActionDefinition;
048import org.kuali.rice.krms.api.repository.context.ContextDefinition;
049import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplaterContract;
050import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
051import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType;
052import org.kuali.rice.krms.api.repository.proposition.PropositionType;
053import org.kuali.rice.krms.api.repository.term.TermDefinition;
054import org.kuali.rice.krms.api.repository.term.TermRepositoryService;
055import org.kuali.rice.krms.impl.repository.language.SimpleNaturalLanguageTemplater;
056
057import static org.kuali.rice.core.api.criteria.PredicateFactory.in;
058
059/**
060 * The implementation of {@link RuleManagementService} operations facilitate management of rules and
061 * associated information.
062 *
063 * @author Kuali Rice Team (rice.collab@kuali.org)
064 */
065public class KSRuleManagementServiceImpl extends RuleRepositoryServiceImpl implements RuleManagementService {
066
067    private ReferenceObjectBindingBoService referenceObjectBindingBoService = new ReferenceObjectBindingBoServiceImpl();
068    private AgendaBoService agendaBoService = new KSAgendaBoServiceImpl();
069    private RuleBoService ruleBoService = new KSRuleBoServiceImpl();
070    private ActionBoService actionBoService = new ActionBoServiceImpl();
071    private PropositionBoService propositionBoService = new PropositionBoServiceImpl();
072    private NaturalLanguageUsageBoService naturalLanguageUsageBoService = new NaturalLanguageUsageBoServiceImpl();
073    private NaturalLanguageTemplateBoService naturalLanguageTemplateBoService = new NaturalLanguageTemplateBoServiceImpl();
074    private ContextBoService contextBoService = new ContextBoServiceImpl();
075    private NaturalLanguageTemplaterContract templater = new SimpleNaturalLanguageTemplater();
076    private TermRepositoryService termRepositoryService = new TermBoServiceImpl();
077    private SequenceAccessorService sequenceAccessorService = null;
078    private TranslateBusinessMethods translationBusinessMethods = null;
079
080    /**
081     * get the {@link ReferenceObjectBindingBoService}
082     * @return the {@link ReferenceObjectBindingBoService}
083     */
084    public ReferenceObjectBindingBoService getReferenceObjectBindingBoService() {
085        return referenceObjectBindingBoService;
086    }
087
088    /**
089     * set the {@link ReferenceObjectBindingBoService}
090     * @param referenceObjectBindingBoService the {@link ReferenceObjectBindingBoService} to set
091     */
092    public void setReferenceObjectBindingBoService(ReferenceObjectBindingBoService referenceObjectBindingBoService) {
093        this.referenceObjectBindingBoService = referenceObjectBindingBoService;
094    }
095
096    /**
097     * get the {@link AgendaBoService}
098     * @return the {@link AgendaBoService}
099     */
100    public AgendaBoService getAgendaBoService() {
101        return agendaBoService;
102    }
103
104    /**
105     * set the {@link AgendaBoService}
106     * @param agendaBoService the {@link AgendaBoService} to set
107     */
108    public void setAgendaBoService(AgendaBoService agendaBoService) {
109        this.agendaBoService = agendaBoService;
110    }
111
112    /**
113     * get the {@link RuleBoService}
114     * @return the {@link RuleBoService}
115     */
116    public RuleBoService getRuleBoService() {
117        return ruleBoService;
118    }
119
120    /**
121     * set the {@link RuleBoService}
122     * @param ruleBoService the {@link RuleBoService} to set
123     */
124    public void setRuleBoService(RuleBoService ruleBoService) {
125        this.ruleBoService = ruleBoService;
126    }
127
128    /**
129     * get the {@link PropositionBoService}
130     * @return the {@link PropositionBoService}
131     */
132    public PropositionBoService getPropositionBoService() {
133        return propositionBoService;
134    }
135
136    /**
137     * set the {@link PropositionBoService}
138     * @param propositionBoService the {@link PropositionBoService} to set
139     */
140    public void setPropositionBoService(PropositionBoService propositionBoService) {
141        this.propositionBoService = propositionBoService;
142    }
143
144    /**
145     * set the {@link NaturalLanguageUsageBoService}
146     * @return the {@link NaturalLanguageUsageBoService}
147     */
148    public NaturalLanguageUsageBoService getNaturalLanguageUsageBoService() {
149        return naturalLanguageUsageBoService;
150    }
151
152    /**
153     * set the {@link NaturalLanguageUsageBoService}
154     * @param naturalLanguageUsageBoService the {@link NaturalLanguageUsageBoService} to set
155     */
156    public void setNaturalLanguageUsageBoService(NaturalLanguageUsageBoService naturalLanguageUsageBoService) {
157        this.naturalLanguageUsageBoService = naturalLanguageUsageBoService;
158    }
159
160    /**
161     * get the {@link NaturalLanguageTemplateBoService}
162     * @return the {@link NaturalLanguageTemplateBoService}
163     */
164    public NaturalLanguageTemplateBoService getNaturalLanguageTemplateBoService() {
165        return naturalLanguageTemplateBoService;
166    }
167
168    /**
169     * set the {@link NaturalLanguageTemplateBoService}
170     * @param naturalLanguageTemplateBoService the {@link NaturalLanguageTemplateBoService} to set
171     */
172    public void setNaturalLanguageTemplateBoService(NaturalLanguageTemplateBoService naturalLanguageTemplateBoService) {
173        this.naturalLanguageTemplateBoService = naturalLanguageTemplateBoService;
174    }
175
176    /**
177     * get the {@link ContextBoService}
178     * @return the {@link ContextBoService}
179     */
180    public ContextBoService getContextBoService() {
181        return contextBoService;
182    }
183
184    /**
185     * set the {@link ContextBoService}
186     * @param contextBoService the {@link ContextBoService} to set
187     */
188    public void setContextBoService(ContextBoService contextBoService) {
189        this.contextBoService = contextBoService;
190    }
191
192    /**
193     * get the {@link ActionBoService}
194     * @return the {@link ActionBoService}
195     */
196    public ActionBoService getActionBoService() {
197        return actionBoService;
198    }
199
200    /**
201     * Set the {@link ActionBoService}
202     * @param actionBoService the {@link ActionBoService} to set
203     */
204    public void setActionBoService(ActionBoService actionBoService) {
205        this.actionBoService = actionBoService;
206    }
207
208    /**
209     * get the {@link NaturalLanguageTemplaterContract}
210     * @return the {@link NaturalLanguageTemplaterContract}
211     */
212    public NaturalLanguageTemplaterContract getTemplater() {
213        return templater;
214    }
215
216    /**
217     * set the {@link NaturalLanguageTemplaterContract}
218     * @param templater the {@link NaturalLanguageTemplaterContract} to set
219     */
220    public void setTemplater(NaturalLanguageTemplaterContract templater) {
221        this.templater = templater;
222    }
223
224    /**
225     * get the {@link TermRepositoryService}
226     * @return the {@link TermRepositoryService}
227     */
228    public TermRepositoryService getTermRepositoryService() {
229        return termRepositoryService;
230    }
231
232    /**
233     * Set the {@link TermRepositoryService}
234     * @param termRepositoryService the {@link TermRepositoryService} to set
235     */
236    public void setTermRepositoryService(TermRepositoryService termRepositoryService) {
237        this.termRepositoryService = termRepositoryService;
238    }
239
240    /**
241     * get the {@link SequenceAccessorService}
242     * @return the {@link SequenceAccessorService}
243     */
244    public SequenceAccessorService getSequenceAccessorService() {
245        if (this.sequenceAccessorService == null) {
246            this.sequenceAccessorService = KRADServiceLocator.getSequenceAccessorService();
247        }
248        return sequenceAccessorService;
249    }
250
251    /**
252     * set the {@link SequenceAccessorService}
253     * @param sequenceAccessorService the {@link SequenceAccessorService} to set
254     */
255    public void setSequenceAccessorService(SequenceAccessorService sequenceAccessorService) {
256        this.sequenceAccessorService = sequenceAccessorService;
257    }
258
259    /**
260     * get the {@link TranslateBusinessMethods}
261     * @return the current {@link TranslateBusinessMethods}
262     */
263    public TranslateBusinessMethods getTranslateBusinessMethods() {
264        if(translationBusinessMethods  == null) {
265            this.translationBusinessMethods  = new KSTranslationUtility(this, getTermRepositoryService(), this.templater);
266        }
267        return this.translationBusinessMethods ;
268    }
269
270    /**
271     * set the {@link TranslateBusinessMethods}
272     * @param translationBusinessMethods the {@link TranslateBusinessMethods} to set
273     */
274    public void setTranslationBusinessMethods (TranslateBusinessMethods  translationBusinessMethods) {
275        this.translationBusinessMethods  = translationBusinessMethods;
276    }
277
278    ////
279    //// reference object binding methods
280    ////
281
282    @Override
283    public ReferenceObjectBinding createReferenceObjectBinding(ReferenceObjectBinding referenceObjectDefinition)
284            throws RiceIllegalArgumentException {
285        //Set the id if it doesn't exist.
286        if (referenceObjectDefinition.getId() == null) {
287            String referenceObjectBindingId = getSequenceAccessorService().getNextAvailableSequenceNumber("KRMS_REF_OBJ_KRMS_OBJ_S", ReferenceObjectBindingBo.class).toString();
288            ReferenceObjectBinding.Builder refBldr = ReferenceObjectBinding.Builder.create(referenceObjectDefinition);
289            refBldr.setId(referenceObjectBindingId);
290            referenceObjectDefinition = refBldr.build();
291        }
292
293        return referenceObjectBindingBoService.createReferenceObjectBinding(referenceObjectDefinition);
294    }
295
296    @Override
297    public ReferenceObjectBinding getReferenceObjectBinding(String id) throws RiceIllegalArgumentException {
298        return referenceObjectBindingBoService.getReferenceObjectBinding(id);
299    }
300
301    @Override
302    public List<ReferenceObjectBinding> getReferenceObjectBindings(List<String> ids) throws RiceIllegalArgumentException {
303        if (ids == null) {
304            throw new IllegalArgumentException("reference binding object ids must not be null");
305        }
306
307        // Fetch BOs
308        List<ReferenceObjectBindingBo> bos = null;
309
310        if (ids.size() == 0) {
311            bos = Collections.emptyList();
312        } else {
313            QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();
314            List<Predicate> pList = new ArrayList<Predicate>();
315            qBuilder.setPredicates(in("id", ids.toArray()));
316            GenericQueryResults<ReferenceObjectBindingBo> results = getCriteriaLookupService().lookup(ReferenceObjectBindingBo.class, qBuilder.build());
317
318            bos = results.getResults();
319        }
320
321        // Translate BOs
322        List<ReferenceObjectBinding> bindings = new LinkedList<ReferenceObjectBinding>();
323        for (ReferenceObjectBindingBo bo : bos) {
324            ReferenceObjectBinding binding = ReferenceObjectBindingBo.to(bo);
325            bindings.add(binding);
326        }
327
328        return Collections.unmodifiableList(bindings);
329    }
330
331    @Override
332    public List<ReferenceObjectBinding> findReferenceObjectBindingsByReferenceObject(String referenceObjectReferenceDiscriminatorType,
333                                                                                     String referenceObjectId)
334            throws RiceIllegalArgumentException {
335        if (referenceObjectReferenceDiscriminatorType == null) {
336            throw new RiceIllegalArgumentException("reference binding object discriminator type must not be null");
337        }
338
339        if (referenceObjectId == null) {
340            throw new RiceIllegalArgumentException("reference object id must not be null");
341        }
342
343        List<ReferenceObjectBinding> list = new ArrayList<ReferenceObjectBinding>();
344        for (ReferenceObjectBinding binding : this.referenceObjectBindingBoService.findReferenceObjectBindingsByReferenceObject(referenceObjectId)) {
345            if (binding.getReferenceDiscriminatorType().equals(referenceObjectReferenceDiscriminatorType)) {
346                list.add(binding);
347            }
348        }
349
350        return list;
351    }
352
353    @Override
354    public List<ReferenceObjectBinding> findReferenceObjectBindingsByReferenceObjectIds(String referenceObjectReferenceDiscriminatorType,
355                                                                                        List<String> referenceObjectIds)
356            throws RiceIllegalArgumentException {
357        if (referenceObjectReferenceDiscriminatorType == null) {
358            throw new RiceIllegalArgumentException("reference binding object discriminator type must not be null");
359        }
360
361        if (referenceObjectIds == null) {
362            throw new RiceIllegalArgumentException("reference object ids must not be null");
363        }
364
365        List<ReferenceObjectBinding> list = new ArrayList<ReferenceObjectBinding>();
366        for(String referenceObjectId : referenceObjectIds){
367            for (ReferenceObjectBinding binding : this.referenceObjectBindingBoService.findReferenceObjectBindingsByReferenceObject(referenceObjectId)) {
368                if (binding.getReferenceDiscriminatorType().equals(referenceObjectReferenceDiscriminatorType)) {
369                    list.add(binding);
370                }
371            }
372        }
373
374        return list;
375    }
376
377    @Override
378    public List<ReferenceObjectBinding> findReferenceObjectBindingsByReferenceDiscriminatorType(String referenceObjectReferenceDiscriminatorType) throws RiceIllegalArgumentException {
379        return referenceObjectBindingBoService.findReferenceObjectBindingsByReferenceDiscriminatorType(referenceObjectReferenceDiscriminatorType);
380    }
381
382    @Override
383    public List<ReferenceObjectBinding> findReferenceObjectBindingsByKrmsDiscriminatorType(String referenceObjectKrmsDiscriminatorType) throws RiceIllegalArgumentException {
384        return referenceObjectBindingBoService.findReferenceObjectBindingsByKrmsDiscriminatorType(referenceObjectKrmsDiscriminatorType);
385    }
386
387    @Override
388    public List<ReferenceObjectBinding> findReferenceObjectBindingsByKrmsObject(String krmsObjectId) throws RiceIllegalArgumentException {
389        return referenceObjectBindingBoService.findReferenceObjectBindingsByKrmsObject(krmsObjectId);
390    }
391
392    @Override
393    public void updateReferenceObjectBinding(ReferenceObjectBinding referenceObjectBindingDefinition)
394            throws RiceIllegalArgumentException {
395        referenceObjectBindingBoService.updateReferenceObjectBinding(referenceObjectBindingDefinition);
396    }
397
398    @Override
399    public void deleteReferenceObjectBinding(String id) throws RiceIllegalArgumentException {
400        referenceObjectBindingBoService.deleteReferenceObjectBinding(id);
401    }
402
403    @Override
404    public List<String> findReferenceObjectBindingIds(QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
405        return referenceObjectBindingBoService.findReferenceObjectBindingIds(queryByCriteria);
406    }
407
408    ////
409    //// agenda
410    ////
411    @Override
412    public AgendaDefinition createAgenda(AgendaDefinition agendaDefinition) throws RiceIllegalArgumentException {
413        return agendaBoService.createAgenda(agendaDefinition);
414    }
415
416    @Override
417    public AgendaDefinition getAgendaByNameAndContextId(String name, String contextId) {
418        return this.agendaBoService.getAgendaByNameAndContextId(name, contextId);
419    }
420
421    @Override
422    public AgendaDefinition findCreateAgenda(AgendaDefinition agendaDefinition) throws RiceIllegalArgumentException {
423        AgendaDefinition existing = this.getAgendaByNameAndContextId(agendaDefinition.getName(), agendaDefinition.getContextId());
424
425        if (existing != null) {
426            existing = this.updateAgendaIfNeeded(agendaDefinition, existing);
427            return existing;
428        }
429
430        return this.createAgenda(agendaDefinition);
431    }
432
433    private AgendaDefinition updateAgendaIfNeeded(AgendaDefinition agenda, AgendaDefinition existing) {
434        if (this.isSame(agenda, existing)) {
435            return existing;
436        }
437
438        AgendaDefinition.Builder bldr = AgendaDefinition.Builder.create(existing);
439        bldr.setActive(agenda.isActive());
440        bldr.setAttributes(agenda.getAttributes());
441        bldr.setContextId(agenda.getContextId());
442
443        if (agenda.getFirstItemId() != null) {
444            bldr.setFirstItemId(agenda.getFirstItemId());
445        }
446
447        bldr.setTypeId(agenda.getTypeId());
448        this.updateAgenda(bldr.build());
449
450        return this.getAgenda(existing.getId());
451    }
452
453    private boolean isSame(AgendaDefinition agenda, AgendaDefinition existing) {
454        if (!this.isSame(agenda.isActive(), existing.isActive())) {
455            return false;
456        }
457
458        if (!this.isSame(agenda.getAttributes(), existing.getAttributes())) {
459            return false;
460        }
461
462        if (!this.isSame(agenda.getContextId(), existing.getContextId())) {
463            return false;
464        }
465
466        if (!this.isSame(agenda.getFirstItemId(), existing.getFirstItemId())) {
467            return false;
468        }
469
470        if (!this.isSame(agenda.getName(), existing.getName())) {
471            return false;
472        }
473
474        if (!this.isSame(agenda.getTypeId(), existing.getTypeId())) {
475            return false;
476        }
477
478        return true;
479    }
480
481    private boolean isSame(boolean o1, boolean o2) {
482        if (o1 && !o2) {
483            return false;
484        }
485
486        if (!o1 && o2) {
487            return false;
488        }
489
490        return true;
491    }
492
493    private boolean isSame(Map<String, String> o1, Map<String, String> o2) {
494        if (o1 == null && o2 != null) {
495            return false;
496        }
497
498        if (o1 != null && o2 == null) {
499            return false;
500        }
501
502        return o1.equals(o2);
503    }
504
505    private boolean isSame(String o1, String o2) {
506        if (o1 == null && o2 != null) {
507            return false;
508        }
509
510        if (o1 != null && o2 == null) {
511            return false;
512        }
513
514        return o1.equals(o2);
515    }
516
517    @Override
518    public AgendaDefinition getAgenda(String id) throws RiceIllegalArgumentException {
519        return agendaBoService.getAgendaByAgendaId(id);
520    }
521
522    @Override
523    public List<AgendaDefinition> getAgendasByContext(String contextId) throws RiceIllegalArgumentException {
524        return agendaBoService.getAgendasByContextId(contextId);
525    }
526
527    @Override
528    public void updateAgenda(AgendaDefinition agendaDefinition) throws RiceIllegalArgumentException {
529        agendaBoService.updateAgenda(agendaDefinition);
530    }
531
532    @Override
533    public void deleteAgenda(String id) throws RiceIllegalArgumentException {
534        agendaBoService.deleteAgenda(id);
535    }
536
537    @Override
538    public List<AgendaDefinition> getAgendasByType(String typeId) throws RiceIllegalArgumentException {
539        return agendaBoService.getAgendasByType(typeId);
540    }
541
542    @Override
543    public List<AgendaDefinition> getAgendasByTypeAndContext(String typeId, String contextId)
544            throws RiceIllegalArgumentException {
545        return agendaBoService.getAgendasByTypeAndContext(typeId, contextId);
546    }
547
548    ////
549    //// agenda item methods
550    ////
551    @Override
552    public AgendaItemDefinition createAgendaItem(AgendaItemDefinition agendaItemDefinition) throws RiceIllegalArgumentException {
553        agendaItemDefinition = createUpdateAgendaItemIfNeeded(agendaItemDefinition);
554        return agendaBoService.createAgendaItem(agendaItemDefinition);
555    }
556
557    private AgendaItemDefinition createUpdateAgendaItemIfNeeded(AgendaItemDefinition agendaItemDefinition) {
558        this.crossCheckRuleId(agendaItemDefinition);
559        this.crossCheckWhenTrueId(agendaItemDefinition);
560        this.crossCheckWhenFalseId(agendaItemDefinition);
561        this.crossCheckAlwaysId(agendaItemDefinition);
562        this.crossCheckSubAgendaId(agendaItemDefinition);
563        agendaItemDefinition = createUpdateRuleIfNeeded(agendaItemDefinition);
564        agendaItemDefinition = createWhenTrueAgendaItemIfNeeded(agendaItemDefinition);
565        agendaItemDefinition = createWhenFalseAgendaItemIfNeeded(agendaItemDefinition);
566        agendaItemDefinition = createAlwaysAgendaItemIfNeeded(agendaItemDefinition);
567        return createSubAgendaIfNeeded(agendaItemDefinition);
568    }
569
570    private void crossCheckRuleId(AgendaItemDefinition agendItemDefinition)
571            throws RiceIllegalArgumentException {
572        // if both are set they better match
573        if (agendItemDefinition.getRuleId() != null && agendItemDefinition.getRule() != null) {
574            if (!agendItemDefinition.getRuleId().equals(agendItemDefinition.getRule().getId())) {
575                throw new RiceIllegalArgumentException("ruleId does not rule.getId" + agendItemDefinition.getRuleId() + " " + agendItemDefinition.getRule().getId());
576            }
577        }
578    }
579
580    private void crossCheckWhenTrueId(AgendaItemDefinition agendaItemDefinition)
581            throws RiceIllegalArgumentException {
582        // if both are set they better match
583        if (agendaItemDefinition.getWhenTrueId()!= null && agendaItemDefinition.getWhenTrue() != null) {
584            if (!agendaItemDefinition.getWhenTrueId().equals(agendaItemDefinition.getWhenTrue().getId())) {
585                throw new RiceIllegalArgumentException("when true id does not match " + agendaItemDefinition.getWhenTrueId() + " " + agendaItemDefinition.getWhenTrue().getId());
586            }
587        }
588    }
589
590    private void crossCheckWhenFalseId(AgendaItemDefinition agendItemDefinition)
591            throws RiceIllegalArgumentException {
592        // if both are set they better match
593        if (agendItemDefinition.getWhenFalseId()!= null && agendItemDefinition.getWhenFalse() != null) {
594            if (!agendItemDefinition.getWhenFalseId().equals(agendItemDefinition.getWhenFalse().getId())) {
595                throw new RiceIllegalArgumentException("when false id does not match " + agendItemDefinition.getWhenFalseId() + " " + agendItemDefinition.getWhenFalse().getId());
596            }
597        }
598    }
599
600    private void crossCheckAlwaysId(AgendaItemDefinition agendItemDefinition)
601            throws RiceIllegalArgumentException {
602        // if both are set they better match
603        if (agendItemDefinition.getAlwaysId()!= null && agendItemDefinition.getAlways() != null) {
604            if (!agendItemDefinition.getAlwaysId().equals(agendItemDefinition.getAlways().getId())) {
605                throw new RiceIllegalArgumentException("Always id does not match " + agendItemDefinition.getAlwaysId() + " " + agendItemDefinition.getAlways().getId());
606            }
607        }
608    }
609
610    private void crossCheckSubAgendaId(AgendaItemDefinition agendItemDefinition)
611            throws RiceIllegalArgumentException {
612        // if both are set they better match
613        if (agendItemDefinition.getSubAgendaId()!= null && agendItemDefinition.getSubAgenda() != null) {
614            if (!agendItemDefinition.getSubAgendaId().equals(agendItemDefinition.getSubAgenda().getId())) {
615                throw new RiceIllegalArgumentException("SubAgenda id does not match " + agendItemDefinition.getSubAgendaId() + " " + agendItemDefinition.getSubAgenda().getId());
616            }
617        }
618    }
619
620    private AgendaItemDefinition createUpdateRuleIfNeeded(AgendaItemDefinition agendaItemDefinition)
621            throws RiceIllegalArgumentException {
622        // no rule to create
623        if (agendaItemDefinition.getRule() == null) {
624            return agendaItemDefinition;
625        }
626
627        // update
628        if (agendaItemDefinition.getRule().getId() != null) {
629            this.updateRule(agendaItemDefinition.getRule());
630            RuleDefinition rule = this.getRule(agendaItemDefinition.getRule ().getId());
631            AgendaItemDefinition.Builder agendaItemBuilder = AgendaItemDefinition.Builder.create(agendaItemDefinition);
632            agendaItemBuilder.setRule(RuleDefinition.Builder.create(rule));
633            agendaItemBuilder.setRuleId(rule.getId());
634
635            return agendaItemBuilder.build();
636        }
637
638        AgendaItemDefinition.Builder agendaItemBuilder = AgendaItemDefinition.Builder.create(agendaItemDefinition);
639        RuleDefinition ruleDefinition = this.createRule(agendaItemDefinition.getRule());
640        RuleDefinition.Builder ruleBuilder = RuleDefinition.Builder.create(ruleDefinition);
641        agendaItemBuilder.setRule(ruleBuilder);
642        agendaItemBuilder.setRuleId(ruleBuilder.getId());
643
644        return agendaItemBuilder.build();
645    }
646
647    private AgendaItemDefinition createWhenTrueAgendaItemIfNeeded(AgendaItemDefinition agendaItemDefinition) {
648        // nothing to create
649        if (agendaItemDefinition.getWhenTrue() == null) {
650            return agendaItemDefinition;
651        }
652
653        // ojb will take care of it if it has already been created
654        if (agendaItemDefinition.getWhenTrue().getId() != null) {
655            return agendaItemDefinition;
656        }
657
658        // ojb does not take care of terms and termparameters, recursively loop thru agendaitems to update terms
659        AgendaItemDefinition.Builder agendaItemBuilder = AgendaItemDefinition.Builder.create(agendaItemDefinition);
660        AgendaItemDefinition subAgendaItem = this.createUpdateAgendaItemIfNeeded(agendaItemDefinition.getWhenTrue());
661        agendaItemBuilder.setWhenTrue(AgendaItemDefinition.Builder.create(subAgendaItem));
662        agendaItemBuilder.setWhenTrueId(subAgendaItem.getId());
663
664        return agendaItemBuilder.build();
665    }
666
667
668    private AgendaItemDefinition createWhenFalseAgendaItemIfNeeded(AgendaItemDefinition agendaItemDefinition) {
669        // nothing to create
670        if (agendaItemDefinition.getWhenFalse() == null) {
671            return agendaItemDefinition;
672        }
673
674        // ojb will take care of it if it has already been created
675        if (agendaItemDefinition.getWhenFalse().getId() != null) {
676            return agendaItemDefinition;
677        }
678
679        // ojb does not take care of terms and termparameters, recursively loop thru agendaitems to update terms
680        AgendaItemDefinition.Builder agendaItemBuilder = AgendaItemDefinition.Builder.create(agendaItemDefinition);
681        AgendaItemDefinition subAgendaItem = this.createUpdateAgendaItemIfNeeded(agendaItemDefinition.getWhenFalse());
682        agendaItemBuilder.setWhenFalse(AgendaItemDefinition.Builder.create(subAgendaItem));
683        agendaItemBuilder.setWhenFalseId(subAgendaItem.getId());
684        return agendaItemBuilder.build();
685    }
686
687
688    private AgendaItemDefinition createAlwaysAgendaItemIfNeeded(AgendaItemDefinition agendaItemDefinition) {
689        // nothing to create
690        if (agendaItemDefinition.getAlways()== null) {
691            return agendaItemDefinition;
692        }
693        // ojb will take care of it if it has already been created
694        if (agendaItemDefinition.getAlways().getId() != null) {
695            return agendaItemDefinition;
696        }
697
698        AgendaItemDefinition.Builder agendaItemBuilder = AgendaItemDefinition.Builder.create(agendaItemDefinition);
699        AgendaItemDefinition subAgendaItem = this.createAgendaItem(agendaItemDefinition.getAlways());
700        agendaItemBuilder.setAlways(AgendaItemDefinition.Builder.create(subAgendaItem));
701        agendaItemBuilder.setAlwaysId(subAgendaItem.getId());
702
703        return agendaItemBuilder.build();
704    }
705
706    private AgendaItemDefinition createSubAgendaIfNeeded(AgendaItemDefinition agendaItemDefinition) {
707        // nothing to create
708        if (agendaItemDefinition.getSubAgenda() == null) {
709            return agendaItemDefinition;
710        }
711
712        // ojb will take care of it if it has already been created
713        if (agendaItemDefinition.getSubAgenda().getId() != null) {
714            return agendaItemDefinition;
715        }
716
717        AgendaItemDefinition.Builder agendaItemBuilder = AgendaItemDefinition.Builder.create(agendaItemDefinition);
718        AgendaDefinition subAgenda = this.createAgenda(agendaItemDefinition.getSubAgenda());
719        agendaItemBuilder.setSubAgenda(AgendaDefinition.Builder.create(subAgenda));
720        agendaItemBuilder.setSubAgendaId(subAgenda.getId());
721
722        return agendaItemBuilder.build();
723    }
724
725    @Override
726    public AgendaItemDefinition getAgendaItem(String id) throws RiceIllegalArgumentException {
727        AgendaItemDefinition agendaItem = agendaBoService.getAgendaItemById(id);
728
729        if (agendaItem != null) {
730            return setTermValuesForAgendaItem(agendaItem).build();
731        }
732
733        return agendaItem;
734    }
735
736    private AgendaItemDefinition.Builder setTermValuesForAgendaItem(AgendaItemDefinition agendaItem) {
737        if (agendaItem == null){
738            return null;
739        }
740
741        AgendaItemDefinition.Builder itemBuiler = AgendaItemDefinition.Builder.create(agendaItem);
742        if (itemBuiler.getRule() != null) {
743            // Set the termValues on the agenda item.
744            PropositionDefinition proposition = agendaItem.getRule().getProposition();
745            if (proposition != null) {
746                proposition = this.orderCompoundPropositionsIfNeeded(proposition);
747                itemBuiler.getRule().setProposition(this.replaceTermValues(proposition));
748            }
749        }
750
751        // Recursively set the term values on child agenda items.
752        itemBuiler.setWhenTrue(setTermValuesForAgendaItem(agendaItem.getWhenTrue()));
753        itemBuiler.setWhenFalse(setTermValuesForAgendaItem(agendaItem.getWhenFalse()));
754        itemBuiler.setAlways(setTermValuesForAgendaItem(agendaItem.getAlways()));
755
756        return itemBuiler;
757    }
758
759    @Override
760    public List<AgendaItemDefinition> getAgendaItemsByType(String typeId)
761            throws RiceIllegalArgumentException {
762        return agendaBoService.getAgendaItemsByType(typeId);
763    }
764
765    @Override
766    public List<AgendaItemDefinition> getAgendaItemsByContext(String contextId) throws RiceIllegalArgumentException {
767        return agendaBoService.getAgendaItemsByContext(contextId);
768    }
769
770    @Override
771    public List<AgendaItemDefinition> getAgendaItemsByTypeAndContext(String typeId, String contextId)
772            throws RiceIllegalArgumentException {
773        return agendaBoService.getAgendaItemsByTypeAndContext(typeId, contextId);
774    }
775
776    @Override
777    public void deleteAgendaItem(String id) throws RiceIllegalArgumentException {
778        agendaBoService.deleteAgendaItem(id);
779    }
780
781    @Override
782    public void updateAgendaItem(AgendaItemDefinition agendaItemDefinition) throws RiceIllegalArgumentException {
783        agendaItemDefinition = createUpdateAgendaItemIfNeeded(agendaItemDefinition);
784        agendaBoService.updateAgendaItem(agendaItemDefinition);
785    }
786
787    private void crossCheckPropId(RuleDefinition ruleDefinition)
788            throws RiceIllegalArgumentException {
789        // if both are set they better match
790        if (ruleDefinition.getPropId() != null && ruleDefinition.getProposition() != null) {
791            if (!ruleDefinition.getPropId().equals(ruleDefinition.getProposition().getId())) {
792                throw new RiceIllegalArgumentException("propId does not match proposition.getId" + ruleDefinition.getPropId() + " " + ruleDefinition.getProposition().getId());
793            }
794        }
795    }
796
797    ////
798    //// rule methods
799    ////
800    @Override
801    public RuleDefinition getRuleByNameAndNamespace(String name, String namespace) {
802        return this.ruleBoService.getRuleByNameAndNamespace(name, namespace);
803    }
804
805
806    @Override
807    public RuleDefinition createRule(RuleDefinition ruleDefinition) throws RiceIllegalArgumentException {
808        if (ruleDefinition.getId() != null) {
809            RuleDefinition orig = this.getRule(ruleDefinition.getId());
810
811            if (orig != null) {
812                throw new RiceIllegalArgumentException(ruleDefinition.getId());
813            }
814        } else {
815            // if no id then set it because it is needed to store propositions connected to this rule
816            String ruleId = getSequenceAccessorService().getNextAvailableSequenceNumber("KRMS_RULE_S", RuleBo.class).toString();
817            RuleDefinition.Builder ruleBldr = RuleDefinition.Builder.create(ruleDefinition);
818            ruleBldr.setId(ruleId);
819            ruleDefinition = ruleBldr.build();
820        }
821
822        // if both are set they better match
823        crossCheckPropId(ruleDefinition);
824        ruleDefinition = this.createUpdatePropositionIfNeeded(ruleDefinition);
825        ruleDefinition = ruleBoService.createRule(ruleDefinition);
826
827        return ruleDefinition;
828    }
829
830    private RuleDefinition createRuleIfNeeded(RuleDefinition ruleDefinition) throws RiceIllegalArgumentException {
831
832        // no rule to create
833        if (ruleDefinition == null) {
834            return null;
835        }
836
837        // if no id then set it because it is needed to store propositions connected to this rule
838        if (ruleDefinition.getId() == null) {
839            String ruleId = getSequenceAccessorService().getNextAvailableSequenceNumber("KRMS_RULE_S", RuleBo.class).toString();
840            RuleDefinition.Builder ruleBldr = RuleDefinition.Builder.create(ruleDefinition);
841            ruleBldr.setId(ruleId);
842            ruleDefinition = ruleBldr.build();
843        }
844
845        // if both are set they better match
846        crossCheckPropId(ruleDefinition);
847        ruleDefinition = this.createUpdatePropositionIfNeeded(ruleDefinition);
848
849        return ruleDefinition;
850    }
851
852    private RuleDefinition createUpdatePropositionIfNeeded(RuleDefinition rule) {
853        // no prop to create
854        if (rule.getProposition() == null) {
855            return rule;
856        }
857
858        // update
859        if (rule.getProposition().getId() != null) {
860            this.updateProposition(rule.getProposition());
861            PropositionDefinition prop = this.getProposition(rule.getProposition().getId());
862            RuleDefinition.Builder ruleBldr = RuleDefinition.Builder.create(rule);
863            ruleBldr.setProposition(PropositionDefinition.Builder.create(prop));
864            ruleBldr.setPropId(prop.getId());
865            return ruleBldr.build();
866        }
867
868        // create the proposition
869        RuleDefinition.Builder ruleBldr = RuleDefinition.Builder.create(rule);
870        PropositionDefinition propositionDefinition = null;
871        // ojb will take care of props that have already been created, but we still need to take care of the terms.
872        PropositionDefinition.Builder propBldr = ruleBldr.getProposition();
873
874        if (rule.getProposition().getId() != null) {
875            this.crossCheckPropositionParameters(rule.getProposition());
876            propBldr = setSequenceOnCompoundPropositionsIfNeeded(propBldr);
877            propBldr = maintainTermValuesAndChildPropositions(propBldr);
878        } else {
879            // create the proposition
880            propBldr.setRule(ruleBldr);
881            propositionDefinition = this.createProposition(propBldr.build());
882            propBldr = PropositionDefinition.Builder.create(propositionDefinition);
883        }
884
885        // now update the rule so it holds the proposition id
886        ruleBldr.setProposition(propBldr);
887
888        return ruleBldr.build();
889    }
890
891    @Override
892    public void updateRule(RuleDefinition ruleDefinition) throws RiceIllegalArgumentException {
893        crossCheckPropId(ruleDefinition);
894        ruleDefinition = this.createUpdatePropositionIfNeeded(ruleDefinition);
895
896        ruleBoService.updateRule(ruleDefinition);
897    }
898
899    @Override
900    public void deleteRule(String id) throws RiceIllegalArgumentException {
901        ruleBoService.deleteRule(id);
902    }
903
904    ////
905    //// action methods
906    ////
907    @Override
908    public ActionDefinition createAction(ActionDefinition actionDefinition) throws RiceIllegalArgumentException {
909        return actionBoService.createAction(actionDefinition);
910    }
911
912    @Override
913    public void updateAction(ActionDefinition actionDefinition) throws RiceIllegalArgumentException {
914        actionBoService.updateAction(actionDefinition);
915    }
916
917    @Override
918    public void deleteAction(String id) throws RiceIllegalArgumentException {
919        throw new RiceIllegalArgumentException("not implemented yet because not supported by the bo service");
920//        actionBoService.deleteAction(id);
921    }
922
923    @Override
924    public ActionDefinition getAction(String actionId) {
925        return actionBoService.getActionByActionId(actionId);
926    }
927
928    @Override
929    public List<ActionDefinition> getActions(List<String> actionIds) {
930        List<ActionDefinition> list = new ArrayList<ActionDefinition>();
931
932        for (String id : actionIds) {
933            list.add(this.getAction(id));
934        }
935
936        return list;
937    }
938
939    private void crossCheckPropositionParameters(PropositionDefinition propositionDefinition) {
940        // check that if the value and termValue are both supplied that they match
941        for (PropositionParameter param : propositionDefinition.getParameters()) {
942            if (param.getValue() != null && param.getTermValue() != null) {
943                if (!param.getValue().equals(param.getTermValue().getId())) {
944                    throw new RiceIllegalArgumentException("value does not match termValue.id on param "
945                            + param.getSequenceNumber() + " " + param.getValue() + " " + param.getTermValue().getId());
946                }
947            }
948        }
949    }
950
951
952    ////
953    //// proposition methods
954    ////
955    @Override
956    public PropositionDefinition createProposition(PropositionDefinition propositionDefinition) throws RiceIllegalArgumentException {
957        // CREATE
958        if (propositionDefinition.getId() != null) {
959            PropositionDefinition orig = this.getProposition(propositionDefinition.getId());
960            if (orig != null) {
961                throw new RiceIllegalArgumentException(propositionDefinition.getId());
962            }
963        }
964
965        crossCheckPropositionParameters(propositionDefinition);
966        PropositionDefinition.Builder propBldr = PropositionDefinition.Builder.create(propositionDefinition);
967        propBldr = setSequenceOnCompoundPropositionsIfNeeded(propBldr);
968        propBldr = maintainTermValuesAndChildPropositions(propBldr);
969        PropositionDefinition prop = propositionBoService.createProposition(propBldr.build());
970
971        return prop;
972    }
973
974    private PropositionDefinition.Builder maintainTermValuesAndChildPropositions(PropositionDefinition.Builder propBldr) {
975        if (PropositionType.SIMPLE.getCode().equalsIgnoreCase(propBldr.getPropositionTypeCode())) {
976            return maintainTermValues(propBldr);
977        } else {
978            return createChildPropsIfNeeded(propBldr);
979        }
980    }
981
982    private PropositionDefinition.Builder maintainTermValues(PropositionDefinition.Builder propBldr) {
983        if (propBldr.getParameters() == null) {
984            return propBldr;
985        }
986
987        if (propBldr.getParameters().isEmpty()) {
988            return propBldr;
989        }
990
991        boolean updated = false;
992        List<PropositionParameter.Builder> paramBldrs = new ArrayList<PropositionParameter.Builder> ();
993
994        for (PropositionParameter.Builder paramBldr : propBldr.getParameters()) {
995            paramBldrs.add(paramBldr);
996
997            // link the param the proposition's id
998            // not sure we need to do this but...
999            if (paramBldr.getPropId() == null) {
1000                paramBldr.setPropId(propBldr.getId());
1001                updated = true;
1002            }
1003
1004            // create the termvalue if it was specified
1005            if (paramBldr.getTermValue() != null) {
1006                TermDefinition termValue = paramBldr.getTermValue();
1007
1008                // no id means it does not exist yet
1009                if (termValue.getId() == null) {
1010                    termValue = this.termRepositoryService.createTerm(termValue);
1011                    paramBldr.setTermValue(termValue);
1012                    updated = true;
1013                } else {
1014                    this.termRepositoryService.updateTerm(termValue);
1015                }
1016
1017                if ((paramBldr.getValue() == null) || (!paramBldr.getValue().equals(termValue.getId()))) {
1018                    paramBldr.setValue(termValue.getId());
1019                    updated = true;
1020                }
1021            }
1022        }
1023
1024        if (!updated) {
1025            return propBldr;
1026        }
1027
1028        propBldr.setParameters(paramBldrs);
1029        return propBldr;
1030    }
1031
1032    private PropositionDefinition.Builder createChildPropsIfNeeded(PropositionDefinition.Builder propBldr) {
1033        if (propBldr.getCompoundComponents() == null) {
1034            return propBldr;
1035        }
1036
1037        if (propBldr.getCompoundComponents().isEmpty()) {
1038            return propBldr;
1039        }
1040
1041        List<PropositionDefinition.Builder> childPropBldrs = new ArrayList<PropositionDefinition.Builder>();
1042
1043        for (PropositionDefinition.Builder compPropBldr : propBldr.getCompoundComponents()) {
1044            compPropBldr.setRuleId(propBldr.getRuleId());
1045            propBldr = setSequenceOnCompoundPropositionsIfNeeded(propBldr);
1046            compPropBldr = maintainTermValuesAndChildPropositions(compPropBldr);
1047            childPropBldrs.add(compPropBldr);
1048        }
1049
1050        propBldr.setCompoundComponents(childPropBldrs);
1051
1052        return propBldr;
1053    }
1054
1055    @Override
1056    public PropositionDefinition getProposition(String id) throws RiceIllegalArgumentException {
1057        if (StringUtils.isBlank(id)) {
1058            throw new RiceIllegalArgumentException("Proposition id must not be null or blank");
1059        }
1060
1061        PropositionDefinition proposition = propositionBoService.getPropositionById(id);
1062
1063        if (proposition == null) {
1064            return null;
1065        }
1066
1067        proposition = this.replaceTermValues(proposition).build();
1068        proposition = this.orderCompoundPropositionsIfNeeded(proposition);
1069
1070        return proposition;
1071    }
1072
1073    private PropositionDefinition orderCompoundPropositionsIfNeeded(PropositionDefinition prop) {
1074        if (!prop.getPropositionTypeCode().equals(PropositionType.COMPOUND.getCode())) {
1075            return prop;
1076        }
1077
1078        if (prop.getCompoundComponents() == null) {
1079            return prop;
1080        }
1081
1082        if (prop.getCompoundComponents().size() <= 1) {
1083            return prop;
1084        }
1085
1086        PropositionDefinition.Builder propBldr = PropositionDefinition.Builder.create(prop);
1087        List<PropositionDefinition> childProps = new ArrayList<PropositionDefinition> (prop.getCompoundComponents());
1088        Collections.sort(childProps, new CompoundPropositionComparator());
1089        List<PropositionDefinition.Builder> childPropBldrs = new ArrayList<PropositionDefinition.Builder> (childProps.size());
1090
1091        for (PropositionDefinition chidProp : childProps) {
1092            PropositionDefinition.Builder childPropBlder = PropositionDefinition.Builder.create(chidProp);
1093            childPropBldrs.add(childPropBlder);
1094        }
1095
1096        propBldr.setCompoundComponents(childPropBldrs);
1097
1098        return propBldr.build();
1099    }
1100
1101    private PropositionDefinition.Builder replaceTermValues(PropositionDefinition proposition) {
1102
1103        PropositionDefinition.Builder bldr = PropositionDefinition.Builder.create(proposition);
1104
1105        // recursively add termValues to child propositions.
1106        if (!PropositionType.SIMPLE.getCode().equalsIgnoreCase(proposition.getPropositionTypeCode())) {
1107            List<PropositionDefinition.Builder> cmpdProps = new ArrayList<PropositionDefinition.Builder>();
1108            for (PropositionDefinition cmpdProp : proposition.getCompoundComponents()) {
1109                cmpdProps.add(replaceTermValues(cmpdProp));
1110            }
1111            bldr.setCompoundComponents(cmpdProps);
1112            return bldr;
1113        }
1114
1115        // that have parameters
1116        if (proposition.getParameters() == null) {
1117            return bldr;
1118        }
1119
1120        if (proposition.getParameters().isEmpty()) {
1121            return bldr;
1122        }
1123
1124        boolean found = false;
1125        List<PropositionParameter.Builder> params = new ArrayList<PropositionParameter.Builder>(proposition.getParameters().size());
1126
1127        for (PropositionParameter param : proposition.getParameters()) {
1128            if (!PropositionParameterType.TERM.getCode().equalsIgnoreCase(param.getParameterType())) {
1129                params.add(PropositionParameter.Builder.create(param));
1130                continue;
1131            }
1132
1133            // inflate the termValue
1134            found = true;
1135            TermDefinition termValue = this.termRepositoryService.getTerm(param.getValue());
1136            PropositionParameter.Builder parmbldr = PropositionParameter.Builder.create(param);
1137            parmbldr.setTermValue(termValue);
1138            params.add(parmbldr);
1139        }
1140
1141        if (!found) {
1142            return bldr;
1143        }
1144
1145        bldr.setParameters(params);
1146
1147        return bldr;
1148    }
1149
1150
1151    private Set<PropositionDefinition> replaceTermValuesInSet(Set<PropositionDefinition> propositions) {
1152        if (propositions == null) {
1153            return null;
1154        }
1155
1156        if (propositions.isEmpty()) {
1157            return propositions;
1158        }
1159
1160        Set<PropositionDefinition> set = new LinkedHashSet<PropositionDefinition>(propositions.size());
1161        for (PropositionDefinition proposition : propositions) {
1162            proposition = this.replaceTermValues(proposition).build();
1163            set.add(proposition);
1164        }
1165
1166        return set;
1167    }
1168
1169    @Override
1170    public Set<PropositionDefinition> getPropositionsByType(String typeId) throws RiceIllegalArgumentException {
1171        return replaceTermValuesInSet(propositionBoService.getPropositionsByType(typeId));
1172    }
1173
1174    @Override
1175    public Set<PropositionDefinition> getPropositionsByRule(String ruleId) throws RiceIllegalArgumentException {
1176        return replaceTermValuesInSet(propositionBoService.getPropositionsByRule(ruleId));
1177    }
1178
1179    @Override
1180    public void updateProposition(PropositionDefinition propositionDefinition) throws RiceIllegalArgumentException {
1181        this.crossCheckPropositionParameters(propositionDefinition);
1182        PropositionDefinition.Builder propBldr = PropositionDefinition.Builder.create(propositionDefinition);
1183        propBldr = setSequenceOnCompoundPropositionsIfNeeded(propBldr);
1184        propBldr = maintainTermValuesAndChildPropositions(propBldr);
1185
1186        propositionBoService.updateProposition(propBldr.build());
1187    }
1188
1189    private PropositionDefinition.Builder setSequenceOnCompoundPropositionsIfNeeded(PropositionDefinition.Builder propBldr) {
1190        if (propBldr.getCompoundComponents() == null) {
1191            return propBldr;
1192        }
1193
1194        if (propBldr.getCompoundComponents().size() <= 1) {
1195            return propBldr;
1196        }
1197
1198        List<PropositionDefinition.Builder> childList = new ArrayList<PropositionDefinition.Builder>(propBldr.getCompoundComponents().size());
1199        int i = 1; // start at 1 because rice does that
1200
1201        for (PropositionDefinition.Builder childPropBldr : propBldr.getCompoundComponents()) {
1202            childPropBldr.setCompoundSequenceNumber(i);
1203            i++;
1204            childList.add(childPropBldr);
1205        }
1206        propBldr.setCompoundComponents(childList);
1207        return propBldr;
1208    }
1209
1210    @Override
1211    public void deleteProposition(String id) throws RiceIllegalArgumentException {
1212        propositionBoService.deleteProposition(id);
1213    }
1214
1215    ////
1216    //// natural language usage methods
1217    ////
1218    @Override
1219    public NaturalLanguageUsage createNaturalLanguageUsage(NaturalLanguageUsage naturalLanguageUsage) throws RiceIllegalArgumentException {
1220        return naturalLanguageUsageBoService.createNaturalLanguageUsage(naturalLanguageUsage);
1221    }
1222
1223    @Override
1224    public NaturalLanguageUsage getNaturalLanguageUsage(String id) throws RiceIllegalArgumentException {
1225        return naturalLanguageUsageBoService.getNaturalLanguageUsage(id);
1226    }
1227
1228    @Override
1229    public void updateNaturalLanguageUsage(NaturalLanguageUsage naturalLanguageUsage) throws RiceIllegalArgumentException {
1230        naturalLanguageUsageBoService.updateNaturalLanguageUsage(naturalLanguageUsage);
1231    }
1232
1233    @Override
1234    public void deleteNaturalLanguageUsage(String naturalLanguageUsageId) throws RiceIllegalArgumentException {
1235        naturalLanguageUsageBoService.deleteNaturalLanguageUsage(naturalLanguageUsageId);
1236    }
1237
1238    @Override
1239    public List<NaturalLanguageUsage> getNaturalLanguageUsagesByNamespace(String namespace)
1240            throws RiceIllegalArgumentException {
1241        return this.naturalLanguageUsageBoService.findNaturalLanguageUsagesByNamespace(namespace);
1242    }
1243
1244    @Override
1245    public NaturalLanguageUsage getNaturalLanguageUsageByNameAndNamespace(String name, String namespace)
1246            throws RiceIllegalArgumentException {
1247        return this.naturalLanguageUsageBoService.getNaturalLanguageUsageByName(namespace, name);
1248    }
1249
1250
1251    ////
1252    //// natural language translations
1253    ////
1254    @Override
1255    public String translateNaturalLanguageForObject(String naturalLanguageUsageId, String typeId, String krmsObjectId,
1256                                                    String languageCode)
1257            throws RiceIllegalArgumentException {
1258
1259        return this.getTranslateBusinessMethods().translateNaturalLanguageForObject(naturalLanguageUsageId, typeId, krmsObjectId, languageCode);
1260    }
1261
1262    @Override
1263    public List<NaturalLanguage> translateNaturalLanguageForObjects(String naturalLanguageUsageId, String typeId, List<String> krmsObjectIds,
1264                                                    String languageCode)
1265            throws RiceIllegalArgumentException {
1266
1267        List<NaturalLanguage> nlList = new ArrayList<NaturalLanguage>();
1268        for(String krmsObjectId : krmsObjectIds){
1269            String nl = this.getTranslateBusinessMethods().translateNaturalLanguageForObject(naturalLanguageUsageId, typeId, krmsObjectId, languageCode);
1270
1271            NaturalLanguage.Builder nlBuilder = NaturalLanguage.Builder.create();
1272            nlBuilder.setKrmsObjectId(krmsObjectId);
1273            nlBuilder.setNaturalLanguage(nl);
1274            nlList.add(nlBuilder.build());
1275        }
1276
1277        return nlList;
1278    }
1279
1280    @Override
1281    public String translateNaturalLanguageForProposition(String naturalLanguageUsageId,
1282                                                         PropositionDefinition proposition, String languageCode)
1283            throws RiceIllegalArgumentException {
1284
1285        return this.getTranslateBusinessMethods().translateNaturalLanguageForProposition(naturalLanguageUsageId, proposition, languageCode);
1286    }
1287
1288    @Override
1289    public NaturalLanguageTree translateNaturalLanguageTreeForProposition(String naturalLanguageUsageId,
1290                                                                          PropositionDefinition propositionDefinintion, String languageCode) throws RiceIllegalArgumentException {
1291
1292        return getTranslateBusinessMethods().translateNaturalLanguageTreeForProposition(naturalLanguageUsageId,
1293                propositionDefinintion, languageCode);
1294    }
1295
1296    ////
1297    //// context methods
1298    ////
1299    @Override
1300    public ContextDefinition createContext(ContextDefinition contextDefinition) throws RiceIllegalArgumentException {
1301        return this.contextBoService.createContext(contextDefinition);
1302    }
1303
1304
1305    @Override
1306    public ContextDefinition findCreateContext(ContextDefinition contextDefinition) throws RiceIllegalArgumentException {
1307        ContextDefinition orig = this.contextBoService.getContextByNameAndNamespace(contextDefinition.getName(), contextDefinition.getNamespace());
1308
1309        if (orig != null) {
1310            return orig;
1311        }
1312
1313        return this.contextBoService.createContext(contextDefinition);
1314    }
1315
1316    @Override
1317    public void updateContext(ContextDefinition contextDefinition) throws RiceIllegalArgumentException {
1318        this.contextBoService.updateContext(contextDefinition);
1319    }
1320
1321    @Override
1322    public void deleteContext(String id) throws RiceIllegalArgumentException {
1323        throw new RiceIllegalArgumentException("not implemented yet");
1324    }
1325
1326    @Override
1327    public ContextDefinition getContext(String id) throws RiceIllegalArgumentException {
1328        return this.contextBoService.getContextByContextId(id);
1329    }
1330
1331    @Override
1332    public ContextDefinition getContextByNameAndNamespace(String name, String namespace) throws RiceIllegalArgumentException {
1333        return this.contextBoService.getContextByNameAndNamespace(name, namespace);
1334    }
1335
1336    ////
1337    //// natural language templates
1338    ////
1339    @Override
1340    public NaturalLanguageTemplate createNaturalLanguageTemplate(NaturalLanguageTemplate naturalLanguageTemplate) throws RiceIllegalArgumentException {
1341        return this.naturalLanguageTemplateBoService.createNaturalLanguageTemplate(naturalLanguageTemplate);
1342    }
1343
1344    @Override
1345    public NaturalLanguageTemplate getNaturalLanguageTemplate(String naturalLanguageTemplateId) throws RiceIllegalArgumentException {
1346        return this.naturalLanguageTemplateBoService.getNaturalLanguageTemplate(naturalLanguageTemplateId);
1347    }
1348
1349    @Override
1350    public void updateNaturalLanguageTemplate(NaturalLanguageTemplate naturalLanguageTemplate) throws RiceIllegalArgumentException {
1351        this.naturalLanguageTemplateBoService.updateNaturalLanguageTemplate(naturalLanguageTemplate);
1352    }
1353
1354    @Override
1355    public void deleteNaturalLanguageTemplate(String naturalLanguageTemplateId) throws RiceIllegalArgumentException {
1356        this.naturalLanguageTemplateBoService.deleteNaturalLanguageTemplate(naturalLanguageTemplateId);
1357    }
1358
1359    @Override
1360    public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByLanguageCode(String languageCode) throws RiceIllegalArgumentException {
1361        return this.naturalLanguageTemplateBoService.findNaturalLanguageTemplatesByLanguageCode(languageCode);
1362    }
1363
1364    @Override
1365    public NaturalLanguageTemplate findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(String languageCode, String typeId, String naturalLanguageUsageId) throws RiceIllegalArgumentException {
1366        return this.naturalLanguageTemplateBoService.findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(languageCode, typeId, naturalLanguageUsageId);
1367    }
1368
1369    @Override
1370    public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByNaturalLanguageUsage(String naturalLanguageUsageId) throws RiceIllegalArgumentException {
1371        return this.naturalLanguageTemplateBoService.findNaturalLanguageTemplatesByNaturalLanguageUsage(naturalLanguageUsageId);
1372    }
1373
1374    @Override
1375    public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByType(String typeId) throws RiceIllegalArgumentException {
1376        return this.naturalLanguageTemplateBoService.findNaturalLanguageTemplatesByType(typeId);
1377    }
1378
1379    @Override
1380    public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByTemplate(String template) throws RiceIllegalArgumentException {
1381        return this.naturalLanguageTemplateBoService.findNaturalLanguageTemplatesByTemplate(template);
1382    }
1383
1384    @Override
1385    public List<String> findContextIds(QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
1386        GenericQueryResults<ContextBo> results = getCriteriaLookupService().lookup(ContextBo.class, queryByCriteria);
1387
1388        List<String> list = new ArrayList<String> ();
1389        for (ContextBo bo : results.getResults()) {
1390            list.add(bo.getId());
1391        }
1392
1393        return list;
1394    }
1395
1396    @Override
1397    public List<String> findAgendaIds(QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
1398        GenericQueryResults<AgendaBo> results = getCriteriaLookupService().lookup(AgendaBo.class, queryByCriteria);
1399        List<String> list = new ArrayList<String> ();
1400
1401        for (AgendaBo bo : results.getResults()) {
1402            list.add(bo.getId());
1403        }
1404
1405        return list;
1406    }
1407
1408    @Override
1409    public List<String> findRuleIds(QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
1410        GenericQueryResults<RuleBo> results = getCriteriaLookupService().lookup(RuleBo.class, queryByCriteria);
1411        List<String> list = new ArrayList<String> ();
1412
1413        for (RuleBo bo : results.getResults()) {
1414            list.add(bo.getId());
1415        }
1416
1417        return list;
1418    }
1419
1420    @Override
1421    public List<String> findPropositionIds(QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
1422        GenericQueryResults<PropositionBo> results = getCriteriaLookupService().lookup(PropositionBo.class, queryByCriteria);
1423
1424        List<String> list = new ArrayList<String> ();
1425        for (PropositionBo bo : results.getResults()) {
1426            list.add(bo.getId());
1427        }
1428
1429        return list;
1430    }
1431
1432    @Override
1433    public List<String> findActionIds(QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
1434        GenericQueryResults<ActionBo> results = getCriteriaLookupService().lookup(ActionBo.class, queryByCriteria);
1435
1436        List<String> list = new ArrayList<String> ();
1437        for (ActionBo bo : results.getResults()) {
1438            list.add(bo.getId());
1439        }
1440
1441        return list;
1442    }
1443
1444    /**
1445     * Sets the businessObjectService property.
1446     *
1447     * @param businessObjectService The businessObjectService to set.
1448     */
1449    @Override
1450    public void setBusinessObjectService(final BusinessObjectService businessObjectService) {
1451        super.setBusinessObjectService(businessObjectService);
1452        if (referenceObjectBindingBoService instanceof ReferenceObjectBindingBoServiceImpl) {
1453            ((ReferenceObjectBindingBoServiceImpl) referenceObjectBindingBoService).setBusinessObjectService(businessObjectService);
1454        }
1455
1456        if (agendaBoService instanceof KSAgendaBoServiceImpl) {
1457            ((KSAgendaBoServiceImpl) agendaBoService).setBusinessObjectService(businessObjectService);
1458        }
1459
1460        if (ruleBoService instanceof KSRuleBoServiceImpl) {
1461            ((KSRuleBoServiceImpl) ruleBoService).setBusinessObjectService(businessObjectService);
1462        }
1463
1464        if (actionBoService instanceof ActionBoServiceImpl) {
1465            ((ActionBoServiceImpl) actionBoService).setBusinessObjectService(businessObjectService);
1466        }
1467
1468        if (propositionBoService instanceof PropositionBoServiceImpl) {
1469            ((PropositionBoServiceImpl) propositionBoService).setBusinessObjectService(businessObjectService);
1470        }
1471
1472        if (naturalLanguageUsageBoService instanceof NaturalLanguageUsageBoServiceImpl) {
1473            ((NaturalLanguageUsageBoServiceImpl) naturalLanguageUsageBoService).setBusinessObjectService(businessObjectService);
1474        }
1475
1476        if (naturalLanguageTemplateBoService instanceof NaturalLanguageTemplateBoServiceImpl) {
1477            ((NaturalLanguageTemplateBoServiceImpl) naturalLanguageTemplateBoService).setBusinessObjectService(businessObjectService);
1478        }
1479
1480        if (contextBoService instanceof ContextBoServiceImpl) {
1481            ((ContextBoServiceImpl) contextBoService).setBusinessObjectService(businessObjectService);
1482        }
1483
1484        if (termRepositoryService instanceof TermBoServiceImpl) {
1485            ((TermBoServiceImpl) termRepositoryService).setBusinessObjectService(businessObjectService);
1486        }
1487    }
1488}
1489