001    package org.kuali.rice.krms.util;
002    
003    import org.apache.commons.lang.BooleanUtils;
004    import org.kuali.rice.krad.uif.UifConstants;
005    import org.kuali.rice.krad.uif.component.Component;
006    import org.kuali.rice.krad.uif.container.Group;
007    import org.kuali.rice.krad.uif.container.LinkGroup;
008    import org.kuali.rice.krad.uif.container.TreeGroup;
009    import org.kuali.rice.krad.uif.element.Action;
010    import org.kuali.rice.krad.uif.element.Link;
011    import org.kuali.rice.krad.uif.field.MessageField;
012    import org.kuali.rice.krad.uif.util.ComponentFactory;
013    import org.kuali.rice.krad.uif.util.ComponentUtils;
014    import org.kuali.rice.krad.uif.view.View;
015    import org.kuali.rice.krad.util.KRADConstants;
016    import org.kuali.rice.krms.dto.*;
017    
018    import java.util.ArrayList;
019    import java.util.List;
020    import java.util.Map;
021    import java.util.Properties;
022    
023    /**
024     * Created with IntelliJ IDEA.
025     * User: danie
026     * Date: 3/7/13
027     * Time: 12:08 PM
028     * To change this template use File | Settings | File Templates.
029     */
030    public class AgendaBuilder {
031    
032        private View view;
033        private Map<String, AgendaTypeInfo> typeRelationsMap;
034    
035        private int agendaCounter;
036        private int ruleCounter;
037    
038        private AlphaIterator alphaIterator = new AlphaIterator();
039    
040        public AgendaBuilder(View view) {
041            this.view = view;
042        }
043    
044        public void setTypeRelationsMap(Map<String, AgendaTypeInfo> typeRelationsMap) {
045            this.typeRelationsMap = typeRelationsMap;
046        }
047    
048        public List<Component> build(RuleManagementWrapper ruleManagementWrapper){
049    
050            // Get the list of existing agendas
051            List<AgendaEditor> agendas = ruleManagementWrapper.getAgendas();
052    
053            // Initialize new array lists.
054            List<AgendaEditor> sortedAgendas = new ArrayList<AgendaEditor>();
055            List<Component> components = new ArrayList<Component>();
056    
057            // Lookup existing agenda by type
058            List<AgendaTypeInfo> agendaTypeInfos = new ArrayList<AgendaTypeInfo>(typeRelationsMap.values());
059            for (AgendaTypeInfo agendaTypeInfo : agendaTypeInfos) {
060                boolean exist = false;
061                for (AgendaEditor agenda : agendas) {
062                    if (agenda.getTypeId().equals(agendaTypeInfo.getId())) {
063                        components.add(this.buildAgenda(agenda));
064                        exist = true;
065                        sortedAgendas.add(agenda);
066                    }
067                }
068                if (!exist) {
069                    AgendaEditor emptyAgenda = new AgendaEditor();
070                    emptyAgenda.setTypeId(agendaTypeInfo.getId());
071                    components.add(this.buildAgenda(emptyAgenda));
072                    sortedAgendas.add(emptyAgenda);
073                }
074            }
075    
076            ruleManagementWrapper.setAgendas(sortedAgendas);
077    
078            return components;
079        }
080    
081        /**
082         * This method dynamically build the components on the screen to render an angenda.
083         *
084         * @param agenda
085         * @return
086         */
087        public Component buildAgenda(AgendaEditor agenda) {
088            // Reset the rule counter.
089            ruleCounter = 0;
090    
091            AgendaTypeInfo agendaType = typeRelationsMap.get(agenda.getTypeId());
092            Group group = (Group) ComponentFactory.getNewComponentInstance("KRMS-AgendaSection-Template");
093            group.setHeaderText(agendaType.getDescription());
094    
095            List<Component> components = new ArrayList<Component>();
096            List<RuleEditor> ruleEditors = new ArrayList<RuleEditor>();
097            for (RuleTypeInfo ruleType : agendaType.getRuleTypes()) {
098    
099                // Add all existing rules of this type.
100                boolean exist = false;
101                if (agenda.getRuleEditors() != null) {
102                    for (RuleEditor rule : agenda.getRuleEditors()) {
103                        if (rule.getTypeId().equals(ruleType.getId()) && (!rule.isDummy())) {
104                            rule.setKey((String)alphaIterator.next());
105                            rule.setRuleTypeInfo(ruleType);
106                            components.add(buildRule(rule, ruleType, this.buildEditRuleSection(rule, ruleType)));
107                            exist = true;
108    
109                            ruleEditors.add(rule);
110                        }
111                    }
112                }
113    
114                // If the ruletype does not exist, add an empty rule section
115                if (!exist) {
116                    RuleEditor ruleEditor = new RuleEditor();
117                    components.add(buildRule(ruleEditor, ruleType, this.buildAddRuleSection(ruleEditor, ruleType)));
118    
119                    ruleEditor.setKey((String)alphaIterator.next());
120                    ruleEditor.setDummy(true);
121                    ruleEditor.setTypeId(ruleType.getId());
122                    ruleEditor.setRuleTypeInfo(ruleType);
123                    ruleEditors.add(ruleEditor);
124                }
125    
126            }
127    
128            group.setItems(components);
129            view.assignComponentIds(group);
130    
131            agendaCounter++;
132            agenda.setRuleEditors(ruleEditors);
133            return group;
134        }
135    
136        /**
137         * This method dynamically builds a disclosure section for each rule that already exists.
138         *
139         * @param rule
140         * @return
141         */
142        protected Component buildRule(RuleEditor rule, RuleTypeInfo ruleTypeInfo, Group ruleSection) {
143            Group group = (Group) ComponentFactory.getNewComponentInstance("KRMS-Rule-Template");
144            group.setHeaderText(ruleTypeInfo.getDescription());
145    
146            //Add edit container to disclosure section
147            List<Component> items = new ArrayList<Component>();
148            items.add(ruleSection);
149            group.setItems(items);
150    
151            ruleCounter++;
152            return group;
153        }
154    
155        protected Group buildEditRuleSection(RuleEditor rule, RuleTypeInfo ruleTypeInfo){
156            Group editSection = (Group) ComponentFactory.getNewComponentInstance("KRMS-RuleEdit-Section");
157            LinkGroup links = (LinkGroup) ComponentUtils.findComponentInList((List<Component>) editSection.getItems(), "KRSM-RuleEdit-ActionLinks");
158            List<Action> actionLinks = (List<Action>) links.getItems();
159            for (Action actionLink : actionLinks) {
160                actionLink.getActionParameters().put("ruleKey", rule.getKey());
161            }
162            MessageField messageField = (MessageField) ComponentUtils.findComponentInList((List<Component>) editSection.getItems(), "KRMS-Instruction-EditMessage");
163            messageField.setMessageText(ruleTypeInfo.getInstruction());
164    
165            Group sectionGroup = (Group) ComponentUtils.findComponentInList((List<Component>) editSection.getItems(), "KRMS-PreviewTree-Group");
166            List<TreeGroup> treeGroups = ComponentUtils.getComponentsOfType((List<Component>) sectionGroup.getItems(), TreeGroup.class);
167            if ((treeGroups != null) && (treeGroups.size() > 0)) {
168                treeGroups.get(0).setPropertyName("agendas[" + agendaCounter + "].ruleEditors[" + ruleCounter + "].viewTree");
169            }
170    
171            return editSection;
172        }
173    
174        /**
175         * This method dynamically builds a disclosure section to allow the user to add a new rule for this rule type.
176         *
177         * @param ruleTypeInfo
178         * @return
179         */
180        protected Group buildAddRuleSection(RuleEditor ruleEditor, RuleTypeInfo ruleTypeInfo) {
181            Group addSection = (Group) ComponentFactory.getNewComponentInstance("KRMS-RuleAdd-Section");
182            LinkGroup links = (LinkGroup) ComponentUtils.findComponentInList((List<Component>) addSection.getItems(), "KRMS-RuleAdd-ActionLink");
183            List<Action> actionLinks = (List<Action>) links.getItems();
184            for (Action actionLink : actionLinks) {
185                actionLink.getActionParameters().put("ruleType", ruleTypeInfo.getId());
186            }
187            MessageField messageField = (MessageField) ComponentUtils.findComponentInList((List<Component>) addSection.getItems(), "KRMS-Instruction-AddMessage");
188            messageField.setMessageText(ruleTypeInfo.getInstruction());
189    
190            return addSection;
191        }
192    
193    }