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