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 }