View Javadoc

1   package org.kuali.rice.krms.service.impl;
2   
3   import org.apache.commons.collections.CollectionUtils;
4   import org.apache.commons.lang.StringUtils;
5   import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
6   import org.kuali.rice.core.api.util.tree.Tree;
7   import org.kuali.rice.krad.uif.component.Component;
8   import org.kuali.rice.krad.uif.container.Container;
9   import org.kuali.rice.krad.uif.container.TabGroup;
10  import org.kuali.rice.krad.uif.util.ComponentFactory;
11  import org.kuali.rice.krad.uif.view.View;
12  import org.kuali.rice.krad.util.GlobalVariables;
13  import org.kuali.rice.krad.util.ObjectUtils;
14  import org.kuali.rice.krad.web.form.MaintenanceDocumentForm;
15  import org.kuali.rice.krms.api.KrmsConstants;
16  import org.kuali.rice.krms.api.repository.LogicalOperator;
17  import org.kuali.rice.krms.api.repository.RuleManagementService;
18  import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
19  import org.kuali.rice.krms.api.repository.language.NaturalLanguageUsage;
20  import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
21  import org.kuali.rice.krms.api.repository.proposition.PropositionDefinitionContract;
22  import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
23  import org.kuali.rice.krms.api.repository.proposition.PropositionParameterContract;
24  import org.kuali.rice.krms.api.repository.proposition.PropositionType;
25  import org.kuali.rice.krms.api.repository.rule.RuleDefinitionContract;
26  import org.kuali.rice.krms.api.repository.term.TermDefinition;
27  import org.kuali.rice.krms.api.repository.term.TermRepositoryService;
28  import org.kuali.rice.krms.api.repository.term.TermResolverDefinition;
29  import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
30  import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService;
31  import org.kuali.rice.krms.api.repository.typerelation.TypeTypeRelation;
32  import org.kuali.rice.krms.builder.ComponentBuilder;
33  import org.kuali.rice.krms.dto.AgendaEditor;
34  import org.kuali.rice.krms.dto.AgendaTypeInfo;
35  import org.kuali.rice.krms.dto.PropositionEditor;
36  import org.kuali.rice.krms.dto.PropositionParameterEditor;
37  import org.kuali.rice.krms.dto.RuleEditor;
38  import org.kuali.rice.krms.dto.RuleManagementWrapper;
39  import org.kuali.rice.krms.dto.RuleTypeInfo;
40  import org.kuali.rice.krms.dto.TermEditor;
41  import org.kuali.rice.krms.dto.TermParameterEditor;
42  import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
43  import org.kuali.rice.krms.impl.util.KRMSPropertyConstants;
44  import org.kuali.rice.krms.impl.util.KrmsImplConstants;
45  import org.kuali.rice.krms.service.TemplateRegistry;
46  import org.kuali.rice.krms.tree.RuleViewTreeBuilder;
47  import org.kuali.rice.krms.tree.node.CompareTreeNode;
48  import org.kuali.rice.krms.tree.RuleCompareTreeBuilder;
49  import org.kuali.rice.krms.tree.RuleEditTreeBuilder;
50  import org.kuali.rice.krms.tree.RulePreviewTreeBuilder;
51  import org.kuali.rice.krms.util.AgendaBuilder;
52  import org.kuali.rice.krms.util.NaturalLanguageHelper;
53  import org.kuali.rice.krms.util.PropositionTreeUtil;
54  import org.kuali.rice.krms.dto.TemplateInfo;
55  import org.kuali.rice.krms.service.RuleViewHelperService;
56  import org.kuali.student.krms.naturallanguage.util.KsKrmsConstants;
57  import org.kuali.student.enrollment.class2.courseoffering.service.decorators.PermissionServiceConstants;
58  import org.kuali.student.enrollment.uif.service.impl.KSViewHelperServiceImpl;
59  
60  import javax.xml.namespace.QName;
61  import java.util.ArrayList;
62  import java.util.Collections;
63  import java.util.HashMap;
64  import java.util.List;
65  import java.util.Map;
66  
67  /**
68   * Created with IntelliJ IDEA.
69   * User: SW
70   * Date: 2012/12/04
71   * Time: 11:52 AM
72   * To change this template use File | Settings | File Templates.
73   */
74  public class RuleViewHelperServiceImpl extends KSViewHelperServiceImpl implements RuleViewHelperService {
75  
76      private transient RuleManagementService ruleManagementService;
77      private transient KrmsTypeRepositoryService krmsTypeRepositoryService;
78      private transient TermRepositoryService termRepositoryService;
79  
80      private RuleCompareTreeBuilder compareTreeBuilder;
81      private RuleEditTreeBuilder editTreeBuilder;
82      private RulePreviewTreeBuilder previewTreeBuilder;
83      private RuleViewTreeBuilder viewTreeBuilder;
84      private NaturalLanguageHelper naturalLanguageHelper;
85  
86      private static TemplateRegistry templateRegistry;
87      private Map<String, AgendaTypeInfo> typeRelationsMap;
88  
89      protected RuleEditor getRuleEditor(Object model) {
90          if (model instanceof MaintenanceDocumentForm) {
91              MaintenanceDocumentForm maintenanceDocumentForm = (MaintenanceDocumentForm) model;
92              Object dataObject = maintenanceDocumentForm.getDocument().getNewMaintainableObject().getDataObject();
93  
94              if (dataObject instanceof RuleEditor) {
95                  return (RuleEditor) dataObject;
96              } else if (dataObject instanceof RuleManagementWrapper) {
97                  RuleManagementWrapper wrapper = (RuleManagementWrapper) dataObject;
98                  return wrapper.getRuleEditor();
99              }
100         }
101         return null;
102     }
103 
104     @Override
105     public String getViewTypeName() {
106         return "kuali.krms.agenda.type.course";
107     }
108 
109     @Override
110     public TemplateInfo getTemplateForType(String type) {
111         return this.getTemplateRegistry().getTemplateForType(type);
112     }
113 
114     @Override
115     protected void addCustomContainerComponents(View view, Object model, Container container) {
116         if ("KS-PropositionEdit-DetailSection".equals(container.getId())) {
117             customizePropositionEditSection(view, model, container);
118         } else if ("KS-RuleEdit-TabSection".equals(container.getId())) {
119             customizeRuleTabSection(view, model, container);
120         } else if ("KRMS-AgendaMaintenance-Page".equals(container.getId())) {
121             customizeAgendaMaintenance(view, model, container);
122         }
123     }
124 
125     private void customizePropositionEditSection(View view, Object model, Container container) {
126         //Retrieve the current editing proposition if exists.
127         RuleEditor ruleEditor = this.getRuleEditor(model);
128         PropositionEditor propEditor = PropositionTreeUtil.getProposition(ruleEditor);
129 
130         List<Component> components = new ArrayList<Component>();
131         if (propEditor != null) {
132             //Retrieve the name of the xml component to display for the proposition type.
133             TemplateInfo template = this.getTemplateForType(propEditor.getType());
134 
135             if (template != null && template.getComponentId() != null) {
136                 Component component = ComponentFactory.getNewComponentInstance(template.getComponentId());
137                 view.assignComponentIds(component);
138 
139                 //Add Proposition Type FieldGroup to Tree Node
140                 components.add(component);
141             }
142 
143             if (template != null && template.getConstantComponentId() != null) {
144                 Component component = ComponentFactory.getNewComponentInstance(template.getConstantComponentId());
145                 view.assignComponentIds(component);
146 
147                 //Add Proposition Type FieldGroup to Tree Node
148                 components.add(component);
149             }
150         }
151 
152         container.setItems(components);
153     }
154 
155     private void customizeRuleTabSection(View view, Object model, Container container) {
156         if (container instanceof TabGroup) {
157             RuleEditor ruleEditor = this.getRuleEditor(model);
158             TabGroup tabGroup = (TabGroup) container;
159             Map<String, String> options = tabGroup.getTabsWidget().getTemplateOptions();
160             if (ruleEditor.getSelectedTab() == null) {
161                 ruleEditor.setSelectedTab("0");
162             }
163             options.put("selected", ruleEditor.getSelectedTab());
164             ruleEditor.setSelectedTab("0");
165         }
166     }
167 
168     private void customizeAgendaMaintenance(View view, Object model, Container container) {
169         AgendaBuilder builder = new AgendaBuilder(view);
170         builder.setTypeRelationsMap(this.getTypeRelationsMap());
171 
172         //Retrieve the current editing proposition if exists.
173         MaintenanceDocumentForm document = (MaintenanceDocumentForm) model;
174         RuleManagementWrapper form = (RuleManagementWrapper) document.getDocument().getNewMaintainableObject().getDataObject();
175 
176         container.setItems(builder.build(form));
177     }
178 
179     /**
180      * Setup a map with all the type information required to build an agenda management page.
181      *
182      * @return
183      */
184     private Map<String, AgendaTypeInfo> getTypeRelationsMap() {
185         if (typeRelationsMap == null) {
186             typeRelationsMap = new HashMap<String, AgendaTypeInfo>();
187 
188             // Get Instruction Usage Id
189             String instructionUsageId = getRuleManagementService().getNaturalLanguageUsageByNameAndNamespace(KsKrmsConstants.KRMS_NL_TYPE_INSTRUCTION,
190                     PermissionServiceConstants.KS_SYS_NAMESPACE).getId();
191 
192             // Get Description Usage Id
193             String descriptionUsageId = getRuleManagementService().getNaturalLanguageUsageByNameAndNamespace(KsKrmsConstants.KRMS_NL_TYPE_DESCRIPTION,
194                     PermissionServiceConstants.KS_SYS_NAMESPACE).getId();
195 
196             // Get the super type.
197             KrmsTypeDefinition requisitesType = this.getKrmsTypeRepositoryService().getTypeByName(PermissionServiceConstants.KS_SYS_NAMESPACE, "kuali.krms.agenda.type.course");
198 
199             // Get all agenda types linked to super type.
200             List<TypeTypeRelation> agendaRelationships = this.getKrmsTypeRepositoryService().findTypeTypeRelationsByFromType(requisitesType.getId());
201             for (TypeTypeRelation agendaRelationship : agendaRelationships) {
202                 AgendaTypeInfo agendaTypeInfo = new AgendaTypeInfo();
203                 agendaTypeInfo.setId(agendaRelationship.getToTypeId());
204                 agendaTypeInfo.setDescription(this.getDescriptionForTypeAndUsage(agendaRelationship.getToTypeId(), descriptionUsageId));
205 
206                 // Get all rule types for each agenda type
207                 List<TypeTypeRelation> ruleRelationships = this.getKrmsTypeRepositoryService().findTypeTypeRelationsByFromType(agendaRelationship.getToTypeId());
208                 List<RuleTypeInfo> ruleTypes = new ArrayList<RuleTypeInfo>();
209                 for (TypeTypeRelation ruleRelationship : ruleRelationships) {
210                     RuleTypeInfo ruleTypeInfo = new RuleTypeInfo();
211                     ruleTypeInfo.setId(ruleRelationship.getToTypeId());
212                     ruleTypeInfo.setDescription(this.getDescriptionForTypeAndUsage(ruleRelationship.getToTypeId(), descriptionUsageId));
213                     if (ruleTypeInfo.getDescription().isEmpty()) {
214                         ruleTypeInfo.setDescription("Description is unset rule type");
215                     }
216                     ruleTypeInfo.setInstruction(this.getDescriptionForTypeAndUsage(ruleRelationship.getToTypeId(), instructionUsageId));
217                     if (ruleTypeInfo.getInstruction().isEmpty()) {
218                         ruleTypeInfo.setInstruction("Instruction is unset for rule type");
219                     }
220                     // Add rule types to list.
221                     ruleTypes.add(ruleTypeInfo);
222                 }
223                 agendaTypeInfo.setRuleTypes(ruleTypes);
224                 typeRelationsMap.put(agendaRelationship.getToTypeId(), agendaTypeInfo);
225             }
226         }
227         return typeRelationsMap;
228     }
229 
230     private String getDescriptionForTypeAndUsage(String typeId, String usageId) {
231         NaturalLanguageTemplate template = null;
232         try {
233             template = getRuleManagementService().findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId("en", typeId, usageId);
234             return template.getTemplate();
235         } catch (Exception e) {
236             return StringUtils.EMPTY;
237         }
238     }
239 
240     /**
241      * finds the term resolver with the fewest parameters that resolves the given term specification
242      *
243      * @param termSpecId the id of the term specification
244      * @param namespace  the  namespace of the term specification
245      * @return the simples {@link org.kuali.rice.krms.api.repository.term.TermResolverDefinition} found, or null if none was found
246      */
247     // public access so that AgendaEditorController can use it too
248     public static TermResolverDefinition getSimplestTermResolver(String termSpecId,
249                                                                  String namespace) {// Get the term resolver for the term spec
250 
251         List<TermResolverDefinition> resolvers =
252                 KrmsRepositoryServiceLocator.getTermBoService().findTermResolversByOutputId(termSpecId, namespace);
253 
254         TermResolverDefinition simplestResolver = null;
255 
256         for (TermResolverDefinition resolver : resolvers) {
257             if (simplestResolver == null ||
258                     simplestResolver.getParameterNames().size() < resolver.getParameterNames().size()) {
259                 simplestResolver = resolver;
260             }
261         }
262 
263         return simplestResolver;
264     }
265 
266     public String resetDescription(PropositionEditor prop) {
267 
268         //If proposition type is null, set description and term null
269         if(prop.getType() == null) {
270             prop.setDescription(StringUtils.EMPTY);
271             prop.setTerm(null);
272             prop.getNaturalLanguage().clear();
273             return prop.getDescription();
274         }
275 
276         //Build the new termParamters with the matching component builder.
277         if (PropositionType.SIMPLE.getCode().equalsIgnoreCase(prop.getPropositionTypeCode())) {
278             Map<String, String> termParameters = null;
279             ComponentBuilder builder = this.getTemplateRegistry().getComponentBuilderForType(prop.getType());
280             if (builder != null) {
281                 termParameters = builder.buildTermParameters(prop);
282             }
283             if (prop.getTerm() == null){
284                 TermEditor term = new TermEditor();
285                 String termSpecName = this.getTemplateRegistry().getTermSpecNameForType(prop.getType());
286                 term.setSpecification(getTermRepositoryService().getTermSpecificationByNameAndNamespace(termSpecName,KsKrmsConstants.NAMESPACE_CODE));
287                 prop.setTerm(term);
288             }
289 
290             List<TermParameterEditor> parameters = new ArrayList<TermParameterEditor>();
291             if (termParameters != null) {
292                 for (Map.Entry<String, String> entry : termParameters.entrySet()) {
293 
294                     TermParameterEditor parameterEditor = null;
295                     if (prop.getTerm().getParameters() != null) {
296                         for (TermParameterEditor parameter : prop.getTerm().getEditorParameters()) {
297 
298                             if (entry.getKey().equals(parameter.getName())) {
299                                 parameterEditor = parameter;
300                                 parameterEditor.setValue(entry.getValue());
301                                 break;
302                             }
303                         }
304                     }
305 
306                     //Create a new parameter if not exist.
307                     if (parameterEditor == null) {
308                         parameterEditor = new TermParameterEditor();
309                         parameterEditor.setName(entry.getKey());
310                         parameterEditor.setValue(entry.getValue());
311                     }
312                     parameters.add(parameterEditor);
313                 }
314             }
315 
316             prop.getTerm().setParameters(parameters);
317         }
318 
319         //Refresh the natural language.
320         this.getNaturalLanguageHelper().setNaturalLanguageForUsage(prop, KsKrmsConstants.KRMS_NL_RULE_EDIT);
321         this.getNaturalLanguageHelper().setNaturalLanguageForUsage(prop, KsKrmsConstants.KRMS_NL_PREVIEW);
322         prop.setDescription(prop.getNaturalLanguageForUsage(KsKrmsConstants.KRMS_NL_RULE_EDIT));
323         return prop.getDescription();
324     }
325 
326     /**
327      * Validate the given proposition and its children.  Note that this method is side-effecting,
328      * when errors are detected with the proposition, errors are added to the error map.
329      *
330      * @param proposition the proposition to validate
331      * @param namespace   the namespace of the parent rule
332      * @return true if the proposition and its children (if any) are considered valid
333      */
334     // TODO also wire up to proposition for faster feedback to the user
335     public boolean validateProposition(PropositionEditor proposition, String namespace) {
336         boolean result = true;
337 
338         if (proposition != null) { // Null props are allowed.
339 
340             if (StringUtils.isBlank(proposition.getCompoundOpCode())) {
341                 // then this is a simple proposition, validate accordingly
342 
343                 result &= validateSimpleProposition(proposition, namespace);
344 
345             } else {
346                 // this is a compound proposition (or it should be)
347                 List<PropositionEditor> compoundComponents = proposition.getCompoundEditors();
348 
349                 if (!CollectionUtils.isEmpty(proposition.getParameters())) {
350                     GlobalVariables.getMessageMap().putError(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
351                             "error.rule.proposition.compound.invalidParameter", proposition.getDescription());
352                     result &= false;
353                 }
354 
355                 // recurse
356                 if (!CollectionUtils.isEmpty(compoundComponents))
357                     for (PropositionEditor childProp : compoundComponents) {
358                         result &= validateProposition(childProp, namespace);
359                     }
360             }
361         }
362 
363         return result;
364     }
365 
366     /**
367      * Validate the given simple proposition.  Note that this method is side-effecting,
368      * when errors are detected with the proposition, errors are added to the error map.
369      *
370      * @param proposition the proposition to validate
371      * @param namespace   the namespace of the parent rule
372      * @return true if the proposition is considered valid
373      */
374     private boolean validateSimpleProposition(PropositionEditor proposition, String namespace) {
375         boolean result = true;
376 
377         String propConstant = null;
378         if (proposition.getParameters().get(1) != null) {
379             propConstant = proposition.getParameters().get(1).getValue();
380         }
381         String operator = null;
382         if (proposition.getParameters().get(2) != null) {
383             operator = proposition.getParameters().get(2).getValue();
384         }
385 
386         String termId = null;
387         if (proposition.getParameters().get(0) != null) {
388             termId = proposition.getParameters().get(0).getValue();
389         }
390         // Simple proposition requires all of propConstant, termId and operator to be specified
391         if (StringUtils.isBlank(termId)) {
392             GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
393                     "error.rule.proposition.simple.blankField", proposition.getDescription(), "Term");
394             result &= false;
395         } else {
396             result = validateTerm(proposition, namespace);
397         }
398         if (StringUtils.isBlank(operator)) {
399             GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
400                     "error.rule.proposition.simple.blankField", proposition.getDescription(), "Operator");
401             result &= false;
402         }
403         if (StringUtils.isBlank(propConstant) && !operator.endsWith("null")) { // ==null and !=null operators have blank values.
404             GlobalVariables.getMessageMap().putErrorForSectionId(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
405                     "error.rule.proposition.simple.blankField", proposition.getDescription(), "Value");
406             result &= false;
407         } else if (operator.endsWith("null")) { // ==null and !=null operators have blank values.
408             if (propConstant != null) {
409                 proposition.getParameters().get(1).setValue(null);
410             }
411         }
412 
413         if (!CollectionUtils.isEmpty(proposition.getCompoundComponents())) {
414             GlobalVariables.getMessageMap().putError(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
415                     "error.rule.proposition.simple.hasChildren", proposition.getDescription());
416             result &= false; // simple prop should not have compound components
417         }
418         return result;
419     }
420 
421     /**
422      * Validate the term in the given simple proposition.  Note that this method is side-effecting,
423      * when errors are detected with the proposition, errors are added to the error map.
424      *
425      * @param proposition the proposition with the term to validate
426      * @param namespace   the namespace of the parent rule
427      * @return true if the proposition's term is considered valid
428      */
429     private boolean validateTerm(PropositionEditor proposition, String namespace) {
430         boolean result = true;
431 
432         String termId = proposition.getParameters().get(0).getValue();
433         if (termId.startsWith(KrmsImplConstants.PARAMETERIZED_TERM_PREFIX)) {
434             // validate parameterized term
435 
436             // is the term name non-blank
437             if (StringUtils.isBlank(proposition.getNewTermDescription())) {
438                 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
439                         "error.rule.proposition.simple.emptyTermName", proposition.getDescription());
440                 result &= false;
441             }
442 
443             String termSpecificationId = termId.substring(KrmsImplConstants.PARAMETERIZED_TERM_PREFIX.length());
444 
445             TermResolverDefinition termResolverDefinition = null;
446             //RuleViewHelperServiceImpl.getSimplestTermResolver(termSpecificationId, namespace);
447 
448             if (termResolverDefinition == null) {
449                 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
450                         "error.rule.proposition.simple.invalidTerm", proposition.getDescription());
451                 result &= false;
452             } else {
453                 List<String> parameterNames = new ArrayList<String>(termResolverDefinition.getParameterNames());
454                 Collections.sort(parameterNames);
455                 //for (String parameterName : parameterNames) {
456                 //if (!proposition.getTermParameters().containsKey(parameterName) ||
457                 //        StringUtils.isBlank(proposition.getTermParameters().get(parameterName))) {
458                 //    GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
459                 //            "error.rule.proposition.simple.missingTermParameter", proposition.getDescription());
460                 //    result &= false;
461                 //    break;
462                 //}
463                 //}
464             }
465 
466         } else {
467             //validate normal term
468             TermDefinition termDefinition = KrmsRepositoryServiceLocator.getTermBoService().getTerm(termId);
469             if (termDefinition == null) {
470                 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
471                         "error.rule.proposition.simple.invalidTerm", proposition.getDescription());
472             } else if (!namespace.equals(termDefinition.getSpecification().getNamespace())) {
473                 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
474                         "error.rule.proposition.simple.invalidTerm", proposition.getDescription());
475             }
476         }
477         return result;
478     }
479 
480     @Override
481     public void refreshInitTrees(RuleEditor rule) {
482 
483         if (rule == null) {
484             return;
485         }
486 
487         // Refresh the natural language if required.
488         if (rule.getProposition() != null) {
489             PropositionEditor root = (PropositionEditor) rule.getProposition();
490             if (!root.getNaturalLanguage().containsKey(this.getEditTreeBuilder().getNaturalLanguageUsageKey())) {
491                 this.getNaturalLanguageHelper().setNaturalLanguageTreeForUsage(root, this.getEditTreeBuilder().getNaturalLanguageUsageKey());
492             }
493             if (!root.getNaturalLanguage().containsKey(this.getPreviewTreeBuilder().getNaturalLanguageUsageKey())) {
494                 this.getNaturalLanguageHelper().setNaturalLanguageTreeForUsage(root, this.getPreviewTreeBuilder().getNaturalLanguageUsageKey());
495             }
496         }
497 
498         //Rebuild the trees
499         rule.setEditTree(this.getEditTreeBuilder().buildTree(rule));
500         rule.setPreviewTree(this.getPreviewTreeBuilder().buildTree(rule));
501 
502         //Also reset the logic expression. Should only be done after editTree is already built.
503         if (rule.getProposition() != null) {
504             rule.setLogicArea(PropositionTreeUtil.configureLogicExpression((PropositionEditor) rule.getProposition()));
505         }
506 
507     }
508 
509     @Override
510     public void refreshViewTree(RuleEditor rule) {
511 
512         if (rule == null) {
513             return;
514         }
515 
516         //Rebuild the trees
517         rule.setViewTree(this.getViewTreeBuilder().buildTree(rule));
518 
519     }
520 
521     @Override
522     public Tree<CompareTreeNode, String> buildCompareTree(RuleDefinitionContract original, String compareToRefObjectId) throws Exception {
523 
524         //Get the CLU Tree.
525         RuleDefinitionContract compare = this.getRuleManagementService().getRule("10063");
526         this.getNaturalLanguageHelper().setNaturalLanguageTreeForUsage((PropositionEditor) compare, this.getPreviewTreeBuilder().getNaturalLanguageUsageKey());
527 
528         //Build the Tree
529         return this.getCompareTreeBuilder().buildTree(original, compare);
530 
531     }
532 
533     @Override
534     public PropositionEditor copyProposition(PropositionEditor oldProposition) {
535         try {
536             PropositionEditor newProposition = (PropositionEditor) ObjectUtils.deepCopy(oldProposition);
537             newProposition.setId(null);
538             newProposition.setKey(null);
539 
540             return newProposition;
541         } catch (Exception e) {
542             return null;
543         }
544     }
545 
546     @Override
547     public PropositionEditor createCompoundPropositionBoStub(PropositionEditor existing, boolean addNewChild) {
548         try {
549             PropositionEditor compound = PropositionTreeUtil.createCompoundPropositionBoStub(existing, addNewChild, this.getPropositionEditorClass());
550             PropositionTreeUtil.setTypeForCompoundOpCode(compound, LogicalOperator.AND.getCode());
551             this.resetDescription(compound);
552             return compound;
553         } catch (Exception e) {
554             return null;
555         }
556     }
557 
558     @Override
559     public PropositionEditor createSimplePropositionBoStub(PropositionEditor sibling) {
560         try {
561             return PropositionTreeUtil.createSimplePropositionBoStub(sibling, this.getPropositionEditorClass());
562         } catch (Exception e) {
563             return null;
564         }
565     }
566 
567     public Class<? extends PropositionEditor> getPropositionEditorClass() {
568         return PropositionEditor.class;
569     }
570 
571     protected RuleManagementService getRuleManagementService() {
572         if (ruleManagementService == null) {
573             ruleManagementService = (RuleManagementService) GlobalResourceLoader.getService(QName.valueOf("ruleManagementService"));
574         }
575         return ruleManagementService;
576     }
577 
578     protected RuleCompareTreeBuilder getCompareTreeBuilder() {
579         if (compareTreeBuilder == null) {
580             compareTreeBuilder = new RuleCompareTreeBuilder();
581             compareTreeBuilder.setRuleManagementService(this.getRuleManagementService());
582         }
583         return compareTreeBuilder;
584     }
585 
586     protected RuleEditTreeBuilder getEditTreeBuilder() {
587         if (editTreeBuilder == null) {
588             editTreeBuilder = new RuleEditTreeBuilder();
589             editTreeBuilder.setRuleManagementService(this.getRuleManagementService());
590         }
591         return editTreeBuilder;
592     }
593 
594     protected RulePreviewTreeBuilder getPreviewTreeBuilder() {
595         if (previewTreeBuilder == null) {
596             previewTreeBuilder = new RulePreviewTreeBuilder();
597             previewTreeBuilder.setRuleManagementService(this.getRuleManagementService());
598         }
599         return previewTreeBuilder;
600     }
601 
602     protected RuleViewTreeBuilder getViewTreeBuilder() {
603         if (viewTreeBuilder == null) {
604             viewTreeBuilder = new RuleViewTreeBuilder();
605             viewTreeBuilder.setRuleManagementService(this.getRuleManagementService());
606         }
607         return viewTreeBuilder;
608     }
609 
610     protected NaturalLanguageHelper getNaturalLanguageHelper() {
611         if (naturalLanguageHelper == null) {
612             naturalLanguageHelper = new NaturalLanguageHelper();
613             naturalLanguageHelper.setRuleManagementService(this.getRuleManagementService());
614         }
615         return naturalLanguageHelper;
616     }
617 
618     protected TemplateRegistry getTemplateRegistry() {
619         if (templateRegistry == null) {
620             templateRegistry = (TemplateRegistry) GlobalResourceLoader.getService(QName.valueOf("templateResolverMockService"));
621         }
622         return templateRegistry;
623     }
624 
625     protected KrmsTypeRepositoryService getKrmsTypeRepositoryService() {
626         if (krmsTypeRepositoryService == null) {
627             krmsTypeRepositoryService = (KrmsTypeRepositoryService) GlobalResourceLoader.getService(new QName(KrmsConstants.Namespaces.KRMS_NAMESPACE_2_0, "krmsTypeRepositoryService"));
628         }
629         return krmsTypeRepositoryService;
630     }
631 
632     public TermRepositoryService getTermRepositoryService() {
633         if (termRepositoryService == null) {
634             termRepositoryService = (TermRepositoryService) GlobalResourceLoader.getService(new QName(KrmsConstants.Namespaces.KRMS_NAMESPACE_2_0, "termRepositoryService"));
635         }
636         return termRepositoryService;
637     }
638 
639 }