package org.jblooming.waf.html.input; import org.jblooming.tracer.Tracer; import org.jblooming.waf.constants.Commands; import org.jblooming.waf.constants.Fields; import org.jblooming.waf.html.core.HtmlBootstrap; import org.jblooming.waf.html.core.JspHelper; import org.jblooming.waf.html.core.JspIncluder; import org.jblooming.waf.html.state.Form; import org.jblooming.waf.settings.I18n; import org.jblooming.waf.view.ClientEntries; import org.jblooming.waf.view.ClientEntry; import org.jblooming.waf.view.PageSeed; import org.jblooming.waf.view.PageState; import javax.servlet.ServletException; import java.io.IOException; import java.util.*; /** * Handles collections associations. Relies on template * <p/> * <a href="/commons/layout/partCollector.jsp">partCollector.jsp</a> * <p/> * There is a complete example of usage in * <p/> * <a href="/test/testCollector.jsp">/test/testCollector.jsp</a> * * @author Pietro Polsinelli ppolsinelli@open-lab.com */ public class Collector extends JspHelper implements HtmlBootstrap { public Form form; public String height; public TreeMap checkBoxes; public static final String DRAW_CANDIDATES = Fields.FORM_PREFIX + "DCND"; public static final String DRAW_CHOSEN = Fields.FORM_PREFIX + "DCHS"; // these do not rely on public String CANDIDATES_LABEL = "Candidates"; public String CHOSEN_LABEL = "Chosen"; public String NO_CANDIDATES = "No candidates"; public String NO_CHOSEN = "No chosen ones"; public String MOVE_ALL_TO_SELECTED_LABEL = ">>"; public String MOVE_ALL_TO_SELECTED_TITLE = "Move all to chosen"; public String MOVE_TO_SELECTED_LABEL = ">"; public String MOVE_TO_SELECTED_TITLE = "Move selected to chosen"; public String MOVE_TO_UNSELECTED_LABEL = "<"; public String MOVE_TO_UNSELECTED_TITLE = "Move selected to candidates"; public String MOVE_ALL_TO_UNSELECTED_LABEL = "<<"; public String MOVE_ALL_TO_UNSELECTED_TITLE = "Move all to candidates"; public String SYNCHRONIZE_LABEL = "<>"; public String SYNCHRONIZE_TITLE = "Synchonize"; public static final String FLD_CAND_HIDDEN_ID = Fields.FORM_PREFIX + "CA_HID"; public static final String FLD_CHS_HIDDEN_ID = Fields.FORM_PREFIX + "CH_HID"; public static final String FLD_CAND_KEY = Fields.FORM_PREFIX + "CND_KEY"; public static final String FLD_CHOSEN_KEY = Fields.FORM_PREFIX + "CHS_KEY"; public static final String FLD_CHECK_ADDITIONAL = Fields.FORM_PREFIX + "F_C_A"; public static final String FLD_RADIO_ADDITIONAL = Fields.FORM_PREFIX + "F_R_A"; /** * needed to change left side of collector with own jspIncluder */ public String customUrlToInclude; public boolean disabled = false; // --- add public JspIncluder jspIncluderChosen; public JspIncluder jspIncluderCandidates; public Collector(String id, String height, Form form) { this.id = id; urlToInclude = "/commons/layout/partCollector.jsp"; this.form = form; this.height = height; } public String getDiscriminator() { return this.getClass().getName(); } public boolean validate(PageState pageState) throws IOException, ServletException { return true; } /** * Moves according to the action the selected ones as client entries to each side * altering the the TreeMap pair {candidates, chosen} * * @param pageState */ public static void move(String id, PageState pageState) { String command = pageState.getCommand(); ClientEntries ces = pageState.getClientEntries(); String candidateFieldPrefix = Collector.getCandidateFieldPrefix(id); String chosenFieldPrefix = Collector.getChosenFieldPrefix(id); if ((Commands.MOVE_ALL_TO_SELECTED + id).equals(command)) moveAll(candidateFieldPrefix, chosenFieldPrefix, ces, pageState); else if ((Commands.MOVE_TO_SELECTED + id).equals(command)) { moveTo(id, FLD_CHOSEN_KEY, chosenFieldPrefix, candidateFieldPrefix, ces, pageState); //move sel chosen to cands } else if ((Commands.MOVE_TO_UNSELECTED + id).equals(command)) { moveTo(id, FLD_CAND_KEY, candidateFieldPrefix, chosenFieldPrefix, ces, pageState); } else if ((Commands.SYNCHRONIZE + id).equals(command)) { synchronize(id, pageState); } else if ((Commands.MOVE_ALL_TO_UNSELECTED + id).equals(command)) moveAll(chosenFieldPrefix, candidateFieldPrefix, ces, pageState); } public static void synchronize(String id, PageState pageState) { moveTo(id, FLD_CHOSEN_KEY, Collector.getChosenFieldPrefix(id), Collector.getCandidateFieldPrefix(id), pageState.getClientEntries(), pageState); moveTo(id, FLD_CAND_KEY, Collector.getCandidateFieldPrefix(id), Collector.getChosenFieldPrefix(id), pageState.getClientEntries(), pageState); } private static void moveTo(String id, String fldKey, String newPrefix, String oldPrefix, ClientEntries ces, PageState pageState) { if (ces.getEntryKeys() != null) { Iterator i = new HashSet(ces.getEntryKeys()).iterator(); while (i.hasNext()) { String key = (String) i.next(); if (key.startsWith(fldKey + id)) { String keyMap = newPrefix + key.substring((fldKey + id).length()); String oldEntry = oldPrefix + keyMap.substring((fldKey + id).length() - 1); pageState.addClientEntry(keyMap, ces.getEntry(oldEntry).stringValueNullIfEmpty()); ces.deleteEntry(oldEntry); } } } } private static void moveAll(String oldField, String newField, ClientEntries ces, PageState pageState) { if (ces.getEntryKeys() != null) { Iterator i = new HashSet(ces.getEntryKeys()).iterator(); while (i.hasNext()) { String key = (String) i.next(); if (key.startsWith(oldField)) { pageState.addClientEntry(newField + key.substring(oldField.length()), ces.getEntry(key).stringValueNullIfEmpty()); ces.deleteEntry(key); } } } } public static boolean isCollectorCommand(String id, String cmd) { return (Commands.MOVE_ALL_TO_SELECTED + id).equals(cmd) || (Commands.MOVE_TO_SELECTED + id).equals(cmd) || (Commands.MOVE_TO_UNSELECTED + id).equals(cmd) || (Commands.MOVE_ALL_TO_UNSELECTED + id).equals(cmd) || (Commands.SYNCHRONIZE + id).equals(cmd); } public static String getCandidateFieldPrefix(String id) { return FLD_CAND_HIDDEN_ID + id; } public static String getChosenFieldPrefix(String id) { return FLD_CHS_HIDDEN_ID + id; } public static String getCandidateCheckValue(String key) { return FLD_CAND_KEY + key.substring(FLD_CHS_HIDDEN_ID.length()); } public static String getCandidateCheckAddPrefix(String id) { return FLD_CHECK_ADDITIONAL + id; } public static void make(String id, TreeMap candidates, TreeMap chosen, PageSeed pageState) { if (candidates != null && candidates.size() > 0) { for (Iterator iterator = candidates.keySet().iterator(); iterator.hasNext();) { Object key = iterator.next(); Object c = candidates.get(key); if (c!=null) pageState.addClientEntry(getCandidateFieldPrefix(id) + key, c.toString()); else Tracer.platformLogger.error("candidates value null for: "+key); } } if (chosen != null && chosen.size() > 0) { for (Iterator iterator = chosen.keySet().iterator(); iterator.hasNext();) { Object key = iterator.next(); if (chosen.get(key)!=null) pageState.addClientEntry(getChosenFieldPrefix(id) + key, chosen.get(key).toString()); } } } public static void clearClientEntry(String collectorID, PageState pageState) { ClientEntries oldEntries = pageState.getClientEntries(); ClientEntries newEntries = new ClientEntries(); if (oldEntries != null && oldEntries.size() > 0) { for (Iterator<String> iterator = oldEntries.getEntryKeys().iterator(); iterator.hasNext();) { String key = iterator.next(); if (!key.startsWith(Collector.getCandidateFieldPrefix(collectorID))) { ClientEntry entry = oldEntries.getEntry(key); newEntries.addEntry(entry); } } } pageState.setClientEntries(newEntries); } /** * Makes a snapshot of current candidates and chosen of the Collector of id <code>id</code> returning them * collected in TreeMap[0],TreeMap[1] respectively. */ public static TreeMap<String,String>[] snapShot(String id, PageSeed pageState) { TreeMap<String,String> cands = new TreeMap<String,String>(); TreeMap<String,String> chosen = new TreeMap<String,String>(); ClientEntries ces = pageState.getClientEntries(); if (ces.getEntryKeys() != null) { Iterator i = new HashSet(ces.getEntryKeys()).iterator(); while (i.hasNext()) { String key = (String) i.next(); if (key.startsWith(Collector.FLD_CAND_HIDDEN_ID + id)) cands.put(key.substring((Collector.FLD_CAND_HIDDEN_ID + id).length()), ces.getEntry(key).stringValueNullIfEmpty() != null ? ces.getEntry(key).stringValueNullIfEmpty() : ""); else if (key.startsWith(Collector.FLD_CHS_HIDDEN_ID + id)) { chosen.put(key.substring((Collector.FLD_CHS_HIDDEN_ID + id).length()), ces.getEntry(key).stringValueNullIfEmpty() != null ? ces.getEntry(key).stringValueNullIfEmpty() : ""); } } } return new TreeMap[]{cands, chosen}; } /** * @param id the collector name * @return a tree map where the key is the hidden value, the value the shown one */ public static TreeMap<String,String> chosen(String id, PageSeed pageState) { return snapShot(id, pageState)[1]; } /** * @param id the collector name * @return a tree map where the key is the hidden value, the value the shown one */ public static TreeMap<String,String> candidates(String id, PageSeed pageState) { return snapShot(id, pageState)[0]; } /** * @return a map with as keys the id of the chosen element, as value a list of its selected checkboxes */ public static Map<String,List<String>> selectedCheckBoxes(String collectorId, PageSeed pageState) { TreeMap<String,List<String>> selChecks = new TreeMap<String,List<String>>(); Set ids = snapShot(collectorId, pageState)[1].keySet(); ClientEntries ces = pageState.getClientEntries(); if (ces.getEntryKeys() != null) { Iterator i = new HashSet(ces.getEntryKeys()).iterator(); while (i.hasNext()) { String key = (String) i.next(); if (key.startsWith(Collector.FLD_CHECK_ADDITIONAL + collectorId)) { String idAndAddFld = key.substring((Collector.FLD_CHECK_ADDITIONAL + collectorId).length()); //find id if (ids != null && ids.size() > 0) { for (Iterator iterator = ids.iterator(); iterator.hasNext();) { String id = (String) iterator.next(); if (idAndAddFld.startsWith(id)) { List checkedForId = (List) selChecks.get(id); if (checkedForId == null) checkedForId = new ArrayList(); checkedForId.add(idAndAddFld.substring(id.length())); selChecks.put(id, checkedForId); } } } } } } return selChecks; } public void setDefaultLabels(PageState pageState) { this.MOVE_ALL_TO_SELECTED_TITLE = I18n.get("MOVE_ALL_TO_SELECTED_TITLE"); this.MOVE_TO_SELECTED_TITLE = I18n.get("MOVE_TO_SELECTED_TITLE"); this.MOVE_TO_UNSELECTED_TITLE = I18n.get("MOVE_TO_UNSELECTED_TITLE"); this.MOVE_ALL_TO_UNSELECTED_TITLE = I18n.get("MOVE_ALL_TO_UNSELECTED_TITLE"); this.NO_CANDIDATES = I18n.get("NO_CANDIDATES"); this.NO_CHOSEN = I18n.get("NO_CHOSEN"); this.CANDIDATES_LABEL = I18n.get("CANDIDATES_LABEL"); this.CHOSEN_LABEL = I18n.get("CHOSEN_LABEL"); } public static void addSelectedCheckBox(String id, String rowId, String checkBoxName, PageState pageState) { pageState.addClientEntry(getCandidateCheckAddPrefix(id) + rowId + checkBoxName, "on"); } public static void preserveChosen(String collectorName, Form f, PageState pageState) { f.url.getClientEntries().addEntries(pageState.getClientEntries().getEntriesStartingWithStripped(Collector.getChosenFieldPrefix(collectorName)).values()); } }