package pt.ist.renderers; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; import pt.ist.renderers.components.HtmlComponent; import pt.ist.renderers.components.HtmlLabel; import pt.ist.renderers.components.HtmlRadioButton; import pt.ist.renderers.components.HtmlRadioButtonList; import pt.ist.renderers.components.converters.BiDirectionalConverter; import pt.ist.renderers.contexts.PresentationContext; import pt.ist.renderers.extensions.converters.DomainObjectKeyConverter; 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; import pt.ist.renderers.utils.RenderUtils; /** * 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 radio button that * allows to choose that particular object. When submiting, the selected object * will be the value passed to the slot. * *

* Example:

* <object A presentation>
* <object B presentation>
* <object C presentation> *
*/ public class RadioButtonListRenderer extends SelectionRenderer { private String format; private String eachClasses; private String eachStyle; private String eachSchema; private String eachLayout; private boolean saveOptions; private String nullOptionKey; private String nullOptionBundle; public String getFormat() { return this.format; } /** * This allows to specify a presentation format for each object. For more * details about the format syntaxt check the {@see FormatRenderer}. * * @property */ public void setFormat(String format) { this.format = format; } /** * 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 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; } /** * Allow to add option null. Need to set the property setNullOptionBundle * * @property */ public void setNullOptionKey(String nullOptionKey) { this.nullOptionKey = nullOptionKey; } public String getNullOptionKey() { return nullOptionKey; } public void setNullOptionBundle(String nullOptionLabel) { this.nullOptionBundle = nullOptionLabel; } public String getNullOptionBundle() { return nullOptionBundle; } @Override protected Layout getLayout(Object object, Class type) { return new RadioButtonListLayout(); } class RadioButtonListLayout extends Layout { @Override public HtmlComponent createComponent(Object object, Class type) { HtmlRadioButtonList listComponent = new HtmlRadioButtonList(); 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(); HtmlLabel label = new HtmlLabel(); if (StringUtils.isEmpty(layout)) { if (Enum.class.isAssignableFrom(obj.getClass()) && StringUtils.isEmpty(getFormat())) { fillBodyForRadioLabel(metaObject, obj, layout, label); } else { label.setText(getObjectLabel(obj)); } } else { fillBodyForRadioLabel(metaObject, obj, layout, label); } label.setStyle(eachStyle); label.setClasses(eachClasses); String optionValue = getConverter() instanceof BiDirectionalConverter ? ((BiDirectionalConverter) getConverter()) .deserialize(obj) : key.toString(); HtmlRadioButton radioButton = listComponent.addOption(label, optionValue); label.setFor(radioButton); if (object != null && object.equals(obj)) { radioButton.setChecked(true); } } if (!StringUtils.isEmpty(getNullOptionKey())) { HtmlLabel label = new HtmlLabel(); label.setText(RenderUtils.getResourceString(getNullOptionBundle(), getNullOptionKey())); HtmlRadioButton addOption = listComponent.addOption(label, DomainObjectKeyConverter.NULL_VALUE_MARKER); if (object == null) { addOption.setChecked(true); } } if (isSaveOptions()) { savePossibleMetaObjects(possibleMetaObjects); } listComponent.setConverter(new SingleSelectOptionConverter(possibleMetaObjects, getConverter())); listComponent.setTargetSlot((MetaSlotKey) getInputContext().getMetaObject().getKey()); return listComponent; } private void fillBodyForRadioLabel(MetaObject metaObject, Object obj, String layout, HtmlLabel label) { PresentationContext newContext = getContext().createSubContext(metaObject); newContext.setLayout(layout); newContext.setRenderMode(RenderMode.getMode("output")); RenderKit kit = RenderKit.getInstance(); HtmlComponent component = kit.render(newContext, obj); label.setBody(component); } 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); } protected String getObjectLabel(Object object) { if (getFormat() != null) { return RenderUtils.getFormattedProperties(getFormat(), object); } return String.valueOf(object); } } }