/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved. * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.web.security; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.extensions.markup.html.form.palette.Palette; import org.apache.wicket.extensions.markup.html.form.palette.component.Recorder; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.FormComponentPanel; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.ResourceModel; import org.geoserver.security.impl.GeoserverUserDao; import org.geoserver.web.wicket.SimpleChoiceRenderer; /** * A form component that can be used to edit user/rule role lists */ @SuppressWarnings("serial") public class RolesFormComponent extends FormComponentPanel { List<String> roles; List<String> choices; TextField newRoleField; Palette rolePalette; public RolesFormComponent(String id, IModel choiceModel, Form form, boolean hasAny) { super(id, choiceModel); roles = GeoserverUserDao.get().getRoles(); if (hasAny) { roles.add(roles.size(), "*"); } choices = new ArrayList<String>((List<String>) choiceModel.getObject()); rolePalette = rolesPalette(new PropertyModel(this, "choices")); rolePalette.setOutputMarkupId(true); add(rolePalette); add(newRoleField = new TextField("newRole", new Model())); newRoleField.setOutputMarkupId(true); add(addRoleButton(form)); } /** * Builds a palette that forces at least one role to be chosen * * @param userModel * @return */ Palette rolesPalette(final IModel choiceModel) { return new Palette("roles", choiceModel, new Model((Serializable) roles), new SimpleChoiceRenderer(), 10, false) { // trick to force the palette to have at least one selected elements // tried with a nicer validator but it's not used at all, the required thing // instead is working (don't know why...) protected Recorder newRecorderComponent() { Recorder rec = super.newRecorderComponent(); rec.setRequired(true); return rec; } /** * Override otherwise the header is not i18n'ized */ public Component newSelectedHeader(final String componentId) { return new Label(componentId, new ResourceModel( "RolesFormComponent.selectedHeader")); } /** * Override otherwise the header is not i18n'ized */ public Component newAvailableHeader(final String componentId) { return new Label(componentId, new ResourceModel( "RolesFormComponent.availableHeader")); } }; } private AjaxButton addRoleButton(Form form) { // have this work without triggering the form validation. This also means // we need to grab the raw value out of the role field AjaxButton button = new AjaxButton("addRole", form) { @Override protected void onSubmit(AjaxRequestTarget target, Form form) { String newRole = newRoleField.getRawInput(); // update the palette if (!"*".equals(newRole)) { // cumbersome trick to force the palette to store the selection in chioces // then we update the chioces and force the component to repaint... rolePalette.getRecorderComponent().validate(); rolePalette.getRecorderComponent().updateModel(); roles.add(newRole); choices.add(newRole); rolePalette.modelChanged(); } // clear the role field newRoleField.clearInput(); target.addComponent(rolePalette); target.addComponent(newRoleField); } }; button.setDefaultFormProcessing(false); return button; } @Override protected void convertInput() { // if we have "*" in the list, only "*" will do for (String role : choices) { if("*".equals(role)) { choices = new ArrayList<String>(); choices.add("*"); } } setConvertedInput(choices); } public Palette getRolePalette() { return rolePalette; } }