package pt.ist.renderers; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.commons.collections.Predicate; import pt.ist.renderers.components.HtmlCheckBox; import pt.ist.renderers.components.HtmlCheckBoxList; import pt.ist.renderers.components.HtmlComponent; import pt.ist.renderers.components.HtmlLabel; import pt.ist.renderers.components.HtmlListItem; import pt.ist.renderers.contexts.PresentationContext; import pt.ist.renderers.layouts.Layout; import pt.ist.renderers.model.MetaObject; import pt.ist.renderers.model.MetaObjectFactory; import pt.ist.renderers.model.MetaObjectKey; import pt.ist.renderers.model.MetaSlotKey; import pt.ist.renderers.schemas.Schema; import pt.ist.renderers.utils.RenderKit; import pt.ist.renderers.utils.RenderMode; /** * This renderer can be used as the input for a list of objects. The list of * objects the user can choose will be presented as an html list were each list * item will contain the presentation of the object and a checkbox that allows * to choose that particular object. When submiting, all the checked objects * will be added to a list and that list will be the value passed to the slot. * *

* Example: *

* * @author cfgi */ public class CheckBoxOptionListRenderer extends SelectionRenderer { private String eachClasses; private String eachStyle; private String eachSchema; private String eachLayout; private boolean saveOptions; private boolean selectAllShown; private String checkBoxClasses; private String checkBoxStyle; private String listItemClasses; private String listItemStyle; private boolean ordered; /** * This property allows you to configure the class attribute for each * object's presentation. * * @property */ public void setEachClasses(String classes) { this.eachClasses = classes; } public String getEachClasses() { return this.eachClasses; } /** * Allows yout to configure the style attribute for each object's * presentation. * * @property */ public void setEachStyle(String style) { this.eachStyle = style; } public String getEachStyle() { return this.eachStyle; } public String getEachLayout() { return eachLayout; } /** * Allows you to choose the layout in wich each object is to be presented. * * @property */ public void setEachLayout(String eachLayout) { this.eachLayout = eachLayout; } public String getEachSchema() { return eachSchema; } /** * Allows you to specify the schema that should be used when presenting each * individual object. * * @property */ public void setEachSchema(String eachSchema) { this.eachSchema = eachSchema; } public boolean isSelectAllShown() { return this.selectAllShown; } /** * Makes the renderer add and option that selects and unselects all the * remaining options. * * @property */ public void setSelectAllShown(boolean selectAllShown) { this.selectAllShown = selectAllShown; } public boolean isSaveOptions() { return saveOptions; } /** * Allows the possible object list to be persisted between requests, meaning * that the provider is invoked only once. * * @property */ public void setSaveOptions(boolean saveOptions) { this.saveOptions = saveOptions; } public String getCheckBoxClasses() { return checkBoxClasses; } /** * Specifies the class applied to the input element * * @property */ public void setCheckBoxClasses(String checkBoxClasses) { this.checkBoxClasses = checkBoxClasses; } public String getCheckBoxStyle() { return checkBoxStyle; } /** * Specifies the style applied to the input element * * @property */ public void setCheckBoxStyle(String checkBoxStyle) { this.checkBoxStyle = checkBoxStyle; } public String getListItemClasses() { return listItemClasses; } /** * Specifies the classes applied to the list element * * @property */ public void setListItemClasses(String listItemClasses) { this.listItemClasses = listItemClasses; } public String getListItemStyle() { return listItemStyle; } /** * Specifies the style applied to the list element * * @property */ public void setListItemStyle(String listItemStyle) { this.listItemStyle = listItemStyle; } public boolean isOrdered() { return ordered; } /** * Specifies if the generated list will be ordered * * @property */ public void setOrdered(boolean ordered) { this.ordered = ordered; } @Override protected Layout getLayout(Object object, Class type) { return new CheckBoxListLayout(); } protected class CheckBoxListLayout extends Layout { @Override public HtmlComponent createComponent(Object object, Class type) { Collection collection = (Collection) object; HtmlCheckBoxList listComponent = new HtmlCheckBoxList(); listComponent.getList().setOrdered(isOrdered()); Schema schema = RenderKit.getInstance().findSchema(getEachSchema()); List possibleMetaObjects; if (hasSavedPossibleMetaObjects()) { possibleMetaObjects = getPossibleMetaObjects(); } else { possibleMetaObjects = new ArrayList(); for (Object possibility : getPossibleObjects()) { possibleMetaObjects.add(MetaObjectFactory.createObject(possibility, schema)); } } for (MetaObject metaObject : possibleMetaObjects) { Object obj = metaObject.getObject(); MetaObjectKey key = metaObject.getKey(); String layout = getEachLayout(); PresentationContext newContext = getContext().createSubContext(metaObject); newContext.setLayout(layout); newContext.setRenderMode(RenderMode.getMode("output")); RenderKit kit = RenderKit.getInstance(); HtmlComponent component = kit.render(newContext, obj); HtmlLabel label = new HtmlLabel(); label.setBody(component); label.setStyle(eachStyle); label.setClasses(eachClasses); HtmlCheckBox checkBox = listComponent.addOption(label, key.toString()); label.setFor(checkBox); checkBox.setClasses(getCheckBoxClasses()); checkBox.setStyle(getCheckBoxStyle()); if (collection != null && collection.contains(obj)) { checkBox.setChecked(true); } } listComponent.setSelectAllShown(listComponent.getList().getItems().size() > 1 && isSelectAllShown()); if (isSaveOptions()) { savePossibleMetaObjects(possibleMetaObjects); } List components = listComponent.getChildren(new Predicate() { @Override public boolean evaluate(Object arg0) { return arg0 instanceof HtmlListItem; } }); for (HtmlComponent component : components) { HtmlListItem listItem = (HtmlListItem) component; listItem.setStyle(getListItemStyle()); listItem.setClasses(getListItemClasses()); } // TODO: make providers only provide a converter for a single object // make a wrapper converter that calls that converter for each value // this allows converters to be used to menus and checkboxes listComponent.setConverter(new MultipleSelectOptionConverter(possibleMetaObjects, getConverter())); listComponent.setTargetSlot((MetaSlotKey) getInputContext().getMetaObject().getKey()); return listComponent; } private boolean hasSavedPossibleMetaObjects() { return getInputContext().getViewState().getLocalAttribute("options") != null; } private List getPossibleMetaObjects() { return (List) getInputContext().getViewState().getLocalAttribute("options"); } private void savePossibleMetaObjects(List possibleMetaObjects) { getInputContext().getViewState().setLocalAttribute("options", possibleMetaObjects); } } }