001package org.kuali.rice.krms.service.impl;
002
003import org.apache.commons.collections.CollectionUtils;
004import org.apache.commons.lang.StringUtils;
005import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
006import org.kuali.rice.core.api.util.tree.Tree;
007import org.kuali.rice.krad.uif.component.Component;
008import org.kuali.rice.krad.uif.container.Container;
009import org.kuali.rice.krad.uif.container.TabGroup;
010import org.kuali.rice.krad.uif.util.ComponentFactory;
011import org.kuali.rice.krad.uif.view.View;
012import org.kuali.rice.krad.util.GlobalVariables;
013import org.kuali.rice.krad.util.ObjectUtils;
014import org.kuali.rice.krad.web.form.MaintenanceDocumentForm;
015import org.kuali.rice.krms.api.KrmsConstants;
016import org.kuali.rice.krms.api.repository.LogicalOperator;
017import org.kuali.rice.krms.api.repository.RuleManagementService;
018import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
019import org.kuali.rice.krms.api.repository.language.NaturalLanguageUsage;
020import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
021import org.kuali.rice.krms.api.repository.proposition.PropositionDefinitionContract;
022import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
023import org.kuali.rice.krms.api.repository.proposition.PropositionParameterContract;
024import org.kuali.rice.krms.api.repository.proposition.PropositionType;
025import org.kuali.rice.krms.api.repository.rule.RuleDefinitionContract;
026import org.kuali.rice.krms.api.repository.term.TermDefinition;
027import org.kuali.rice.krms.api.repository.term.TermRepositoryService;
028import org.kuali.rice.krms.api.repository.term.TermResolverDefinition;
029import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
030import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService;
031import org.kuali.rice.krms.api.repository.typerelation.TypeTypeRelation;
032import org.kuali.rice.krms.builder.ComponentBuilder;
033import org.kuali.rice.krms.dto.AgendaEditor;
034import org.kuali.rice.krms.dto.AgendaTypeInfo;
035import org.kuali.rice.krms.dto.PropositionEditor;
036import org.kuali.rice.krms.dto.PropositionParameterEditor;
037import org.kuali.rice.krms.dto.RuleEditor;
038import org.kuali.rice.krms.dto.RuleManagementWrapper;
039import org.kuali.rice.krms.dto.RuleTypeInfo;
040import org.kuali.rice.krms.dto.TermEditor;
041import org.kuali.rice.krms.dto.TermParameterEditor;
042import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
043import org.kuali.rice.krms.impl.util.KRMSPropertyConstants;
044import org.kuali.rice.krms.impl.util.KrmsImplConstants;
045import org.kuali.rice.krms.service.TemplateRegistry;
046import org.kuali.rice.krms.tree.RuleViewTreeBuilder;
047import org.kuali.rice.krms.tree.node.CompareTreeNode;
048import org.kuali.rice.krms.tree.RuleCompareTreeBuilder;
049import org.kuali.rice.krms.tree.RuleEditTreeBuilder;
050import org.kuali.rice.krms.tree.RulePreviewTreeBuilder;
051import org.kuali.rice.krms.util.AgendaBuilder;
052import org.kuali.rice.krms.util.NaturalLanguageHelper;
053import org.kuali.rice.krms.util.PropositionTreeUtil;
054import org.kuali.rice.krms.dto.TemplateInfo;
055import org.kuali.rice.krms.service.RuleViewHelperService;
056import org.kuali.student.krms.naturallanguage.util.KsKrmsConstants;
057import org.kuali.student.enrollment.class2.courseoffering.service.decorators.PermissionServiceConstants;
058import org.kuali.student.enrollment.uif.service.impl.KSViewHelperServiceImpl;
059
060import javax.xml.namespace.QName;
061import java.util.ArrayList;
062import java.util.Collections;
063import java.util.HashMap;
064import java.util.List;
065import java.util.Map;
066
067/**
068 * Created with IntelliJ IDEA.
069 * User: SW
070 * Date: 2012/12/04
071 * Time: 11:52 AM
072 * To change this template use File | Settings | File Templates.
073 */
074public class RuleViewHelperServiceImpl extends KSViewHelperServiceImpl implements RuleViewHelperService {
075
076    private transient RuleManagementService ruleManagementService;
077    private transient KrmsTypeRepositoryService krmsTypeRepositoryService;
078    private transient TermRepositoryService termRepositoryService;
079
080    private RuleCompareTreeBuilder compareTreeBuilder;
081    private RuleEditTreeBuilder editTreeBuilder;
082    private RulePreviewTreeBuilder previewTreeBuilder;
083    private RuleViewTreeBuilder viewTreeBuilder;
084    private NaturalLanguageHelper naturalLanguageHelper;
085
086    private static TemplateRegistry templateRegistry;
087    private Map<String, AgendaTypeInfo> typeRelationsMap;
088
089    protected RuleEditor getRuleEditor(Object model) {
090        if (model instanceof MaintenanceDocumentForm) {
091            MaintenanceDocumentForm maintenanceDocumentForm = (MaintenanceDocumentForm) model;
092            Object dataObject = maintenanceDocumentForm.getDocument().getNewMaintainableObject().getDataObject();
093
094            if (dataObject instanceof RuleEditor) {
095                return (RuleEditor) dataObject;
096            } else if (dataObject instanceof RuleManagementWrapper) {
097                RuleManagementWrapper wrapper = (RuleManagementWrapper) dataObject;
098                return wrapper.getRuleEditor();
099            }
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}