Commit f54cddee authored by Gianluca Filippone's avatar Gianluca Filippone
Browse files

Console UI corrections

parent 019bce42
......@@ -636,7 +636,7 @@ we are happy to inform you that the password request was execute successfully fo
<!-- [END] CHOReVOLUTION -->
 
<!-- [START Choreographies -->
<SyncopeGroup id="80b8ba87-842d-481a-b8ba-87842d681a70" name="In-store Marketing and Sale Choreography"
<SyncopeGroup id="80b8ba87-842d-481a-b8ba-87842d681a70" name="In-store Marketing and Sales"
realm_id="ea696a4f-e77a-4ef1-be67-8f8093bc8686"
creator="admin" lastModifier="admin"
creationDate="2016-07-20 11:00:00" lastChangeDate="2016-07-20 11:00:00"/>
......@@ -832,7 +832,7 @@ we are happy to inform you that the password request was execute successfully fo
<!-- [END] WP7 Services -->
 
<!-- [START] Choreography Execution Data -->
<ChoreographyInstances id="3e43032c-9501-4b39-8303-2c9501bb3942" choreographyInstanceid="1" description="WP7 Choreography Instance" choreographyid="xx45671"/>
<ChoreographyInstances id="3e43032c-9501-4b39-8303-2c9501bb3942" choreographyInstanceid="1" description="Instance 1" choreographyid="xx45671"/>
<Events id="0038eb2a-bf5b-4744-b8eb-2abf5bc744c5" artifactName="CD-Client-Smartcart" artifactRole="CD-Selfcheckoutmachine-Marketingapplication" artifactType="0" eventTimestamp="1465990253190" eventType="7" operationName="subscribeUserToCart" sourceState="S10" targetState="S11" choreographyInstance_id="3e43032c-9501-4b39-8303-2c9501bb3942"/>
<Events id="00a3b208-3f4c-421c-a3b2-083f4ca21cbf" artifactName="CD-Client-Selfcheckoutmachine" artifactRole="CD-Selfcheckoutmachine-Marketingapplication" artifactType="0" eventTimestamp="1465990258287" eventType="4" operationName="checkout" sourceState="S22" targetState="S23" choreographyInstance_id="3e43032c-9501-4b39-8303-2c9501bb3942"/>
<Events id="00bf9735-e5d5-4fb0-bf97-35e5d59fb0b4" artifactName="CD-Selfcheckoutmachine-Marketingapplication" artifactRole="CD-Selfcheckoutmachine-Marketingapplication" artifactType="0" eventTimestamp="1465990263309" eventType="5" operationName="notifyCheckout" sourceState="S19" targetState="S21" choreographyInstance_id="3e43032c-9501-4b39-8303-2c9501bb3942"/>
......@@ -22,7 +22,7 @@ import java.util.List;
import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
import org.apache.syncope.client.console.panels.ChoreographyOverviewPanel;
import org.apache.syncope.client.console.panels.ChoreographyServiceDirectoryPanel;
import org.apache.syncope.client.console.panels.EEResourcesPanel;
import org.apache.syncope.client.console.panels.ChoreographyEEResourcesPanel;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.syncope.client.console.panels.InstancesOverviewPanel;
import org.apache.syncope.client.console.rest.ChoreographyRestClient;
......@@ -87,7 +87,7 @@ public class ChoreographyDetailPage extends BaseExtPage {
tabs.add(new AbstractTab(new ResourceModel("eeResources")) {
@Override
public WebMarkupContainer getPanel(final String panelId) {
return new EEResourcesPanel(panelId, getPageReference(), choreographyId);
return new ChoreographyEEResourcesPanel(panelId, getPageReference(), choreographyId);
}
});
......
......@@ -26,7 +26,7 @@ import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.RepeatingView;
public class EEResourcesPanel extends Panel {
public class ChoreographyEEResourcesPanel extends Panel {
private final ChoreographyRestClient restClient;
......@@ -34,12 +34,12 @@ public class EEResourcesPanel extends Panel {
private final EEStatisticBundle bundle;
public EEResourcesPanel(final String id, final PageReference pageRef, final String choreographyId) {
public ChoreographyEEResourcesPanel(final String id, final PageReference pageRef, final String choreographyId) {
super(id);
this.restClient = new ChoreographyRestClient();
this.enactmentEngine = restClient.getChoreographyEE(choreographyId);
this.bundle = new EEStatisticBundle(restClient.getEEVmList(enactmentEngine.getKey()));
this.bundle = new EEStatisticBundle(restClient.getChoreographyVmList(enactmentEngine.getKey(), choreographyId));
add(new Label("eeName", getString("enactmentEngine") + " " + enactmentEngine.getName()));
......@@ -48,7 +48,7 @@ public class EEResourcesPanel extends Panel {
resourcesOverview.newChildId(),
"bg-yellow", bundle.virtualMachines, "Virtual Machines", "fa fa-cube"));
resourcesOverview.add(new ResourceWidget(
resourcesOverview.newChildId(), "bg-red", bundle.cpus, "CPU", "fa fa-cogs"));
resourcesOverview.newChildId(), "bg-red", "CPU utilization", bundle.percentageCPU, "fa fa-cogs"));
resourcesOverview.add(new ResourceWidget(
resourcesOverview.newChildId(),
"bg-green", bundle.usedRam, bundle.totalRam, "RAM utilization", bundle.percentageRam, "MB", ""));
......@@ -58,7 +58,7 @@ public class EEResourcesPanel extends Panel {
"Storage occupancy", bundle.percentageStorage, "GB", "fa fa-database"));
add(resourcesOverview);
add(new ChoreographyVMDirectoryPanel("virtualMachinesList", pageRef, enactmentEngine.getKey()));
add(new ChoreographyVMDirectoryPanel("virtualMachinesList", pageRef, enactmentEngine.getKey(), choreographyId));
}
private class EEStatisticBundle implements Serializable {
......@@ -69,6 +69,8 @@ public class EEResourcesPanel extends Panel {
private int cpus;
private double percentageCPU;
private int usedRam;
private int totalRam;
......@@ -90,6 +92,8 @@ public class EEResourcesPanel extends Panel {
this.usedStorage = 0;
this.totalStorage = 0;
double cpuUtilization = 0;
for (VirtualMachineInfoTO vm: vms) {
this.virtualMachines ++;
this.cpus += vm.getCpuNumber();
......@@ -97,8 +101,11 @@ public class EEResourcesPanel extends Panel {
this.totalRam += vm.getTotalRam();
this.usedStorage += vm.getUsedStorage();
this.totalStorage += vm.getTotalStorage();
cpuUtilization += vm.getCpuNumber() * vm.getCpuUtilization();
}
this.percentageCPU = Math.round(100 * (cpuUtilization / Float.valueOf(cpus))) / 100d;
this.percentageRam = Math.round(10000 * (usedRam / Float.valueOf(totalRam))) / 100d;
this.percentageStorage = Math.round(10000 * (usedStorage / Float.valueOf(totalStorage)) / 100d);
}
......
......@@ -51,10 +51,12 @@ public class ChoreographyVMDirectoryPanel extends DirectoryPanel<
private String enactmentEngineKey;
private String choreographyId;
private final BaseModal<Serializable> utilityModal = new BaseModal<>("outer");
public ChoreographyVMDirectoryPanel(final String id, final PageReference pageRef,
final String enactmentEngineKey) {
final String enactmentEngineKey, final String choreographyId) {
super(id, new DirectoryPanel.Builder<VirtualMachineInfoTO, VirtualMachineInfoTO, ChoreographyRestClient>(
new ChoreographyRestClient(), pageRef) {
......@@ -68,6 +70,7 @@ public class ChoreographyVMDirectoryPanel extends DirectoryPanel<
}.disableCheckBoxes());
this.enactmentEngineKey = enactmentEngineKey;
this.choreographyId = choreographyId;
setFooterVisibility(true);
addOuterObject(utilityModal);
......@@ -130,19 +133,21 @@ public class ChoreographyVMDirectoryPanel extends DirectoryPanel<
public void populateItem(final Item<ICellPopulator<VirtualMachineInfoTO>> item, final String componentId,
final IModel<VirtualMachineInfoTO> model) {
ChoreographyActionsPanel choreographyActionsPanel = new ChoreographyActionsPanel(componentId);
choreographyActionsPanel.addAction(new IndicatingAjaxLink<Void>("link") {
private static final long serialVersionUID = 3104631231085231035L;
@Override
public void onClick(final AjaxRequestTarget target) {
utilityModal.header(Model.of("Resize"));
utilityModal.setContent(new ResizeModalPanel(
utilityModal, model.getObject(), pageRef));
utilityModal.show(true);
target.add(utilityModal);
}
}, ChoreographyActionsPanel.ChoreographyActionType.RESIZE);
if (model.getObject().getType().equals("Choreography")) {
choreographyActionsPanel.addAction(new IndicatingAjaxLink<Void>("link") {
private static final long serialVersionUID = 3104631231085231035L;
@Override
public void onClick(final AjaxRequestTarget target) {
utilityModal.header(Model.of("Resize"));
utilityModal.setContent(new ResizeModalPanel(
utilityModal, model.getObject(), pageRef));
utilityModal.show(true);
target.add(utilityModal);
}
}, ChoreographyActionsPanel.ChoreographyActionType.RESIZE);
}
choreographyActionsPanel.addAction(new IndicatingAjaxLink<Void>("link") {
private static final long serialVersionUID = 3104631231085231035L;
......@@ -173,16 +178,14 @@ public class ChoreographyVMDirectoryPanel extends DirectoryPanel<
@Override
public Iterator<VirtualMachineInfoTO> iterator(final long first, final long count) {
List<VirtualMachineInfoTO> list = restClient.getEEVmList(enactmentEngineKey);
//List<VirtualMachineInfoTO> list = this.getData();
List<VirtualMachineInfoTO> list = restClient.getChoreographyVmList(enactmentEngineKey, choreographyId);
Collections.sort(list, comparator);
return list.subList((int) first, (int) first + (int) count).iterator();
}
@Override
public long size() {
return restClient.getEEVmList(enactmentEngineKey).size();
//return this.getData().size();
return restClient.getChoreographyVmList(enactmentEngineKey, choreographyId).size();
}
@Override
......
......@@ -127,7 +127,14 @@ public class ChoreographyRestClient extends BaseRestClient {
return getService(ChoreographyService.class).getEnactmentEngine(choreographyId);
}
public List<VirtualMachineInfoTO> getEEVmList(final String enactmentEngineKey) {
public List<VirtualMachineInfoTO> getChoreographyVmList(
final String enactmentEngineKey,
final String choreographyId) {
return getService(ChoreographyService.class).getChoreographyVmList(enactmentEngineKey, choreographyId);
}
public List<VirtualMachineInfoTO> getEEVmList(
final String enactmentEngineKey) {
return getService(ChoreographyService.class).getEEVmList(enactmentEngineKey);
}
}
......@@ -18,7 +18,7 @@ limitations under the License.
<wicket:extend>
<section class="content-header">
<h1>
<span wicket:id="header"></span>
<wicket:message key="choreography"/> <span wicket:id="header"></span>
</h1>
<ol class="breadcrumb">
<li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
......
......@@ -52,7 +52,7 @@ limitations under the License.
</wicket:fragment>
<wicket:fragment wicket:id="resizeFragment">
<a href="#" wicket:id="link" class="btn"><i class="fa fa-arrows" alt="resize icon" title="Resize"></i></a>
<a href="#" wicket:id="link" class="btn"><i class="fa fa-expand" alt="resize icon" title="Resize"></i></a>
</wicket:fragment>
<wicket:fragment wicket:id="editFragment">
......
......@@ -787,7 +787,7 @@ public class ChoreographyLogic extends AbstractLogic<AbstractBaseBean> {
info1.setTotalRam(4096);
info1.setUsedStorage(100);
info1.setTotalStorage(1000);
info1.setType("TYPE");
info1.setType("Choreography");
list.add(info1);
VirtualMachineInfoTO info2 = new VirtualMachineInfoTO();
......@@ -799,7 +799,64 @@ public class ChoreographyLogic extends AbstractLogic<AbstractBaseBean> {
info2.setTotalRam(1048);
info2.setUsedStorage(100);
info2.setTotalStorage(512);
info2.setType("TYPE");
info2.setType("Load Balancer");
list.add(info2);
VirtualMachineInfoTO info3 = new VirtualMachineInfoTO();
info3.setId("vm003");
info3.setOs("Ubuntu 16.10");
info3.setCpuNumber(4);
info3.setCpuUtilization(26.5);
info3.setUsedRam(2230);
info3.setTotalRam(4096);
info3.setUsedStorage(88);
info3.setTotalStorage(512);
info3.setType("Choreography");
list.add(info3);
VirtualMachineInfoTO info4 = new VirtualMachineInfoTO();
info4.setId("vm004");
info4.setOs("Ubuntu 16.10");
info4.setCpuNumber(4);
info4.setCpuUtilization(44);
info4.setUsedRam(750);
info4.setTotalRam(4096);
info4.setUsedStorage(340);
info4.setTotalStorage(1000);
info4.setType("Choreography");
list.add(info4);
return list;
}
@PreAuthorize("hasRole('" + ChorevolutionEntitlement.CHOREOGRAPHY_LIST + "')")
public List<VirtualMachineInfoTO> getChoreographyVmList(
final String enactmentEngineKey,
final String choreographyId) {
List<VirtualMachineInfoTO> list = new ArrayList<>();
VirtualMachineInfoTO info1 = new VirtualMachineInfoTO();
info1.setId("vm001");
info1.setOs("Ubuntu 16.10");
info1.setCpuNumber(4);
info1.setCpuUtilization(30.5);
info1.setUsedRam(1500);
info1.setTotalRam(4096);
info1.setUsedStorage(100);
info1.setTotalStorage(1000);
info1.setType("Choreography");
list.add(info1);
VirtualMachineInfoTO info2 = new VirtualMachineInfoTO();
info2.setId("vm002");
info2.setOs("Ubuntu 16.10");
info2.setCpuNumber(2);
info2.setCpuUtilization(51);
info2.setUsedRam(400);
info2.setTotalRam(1048);
info2.setUsedStorage(100);
info2.setTotalStorage(512);
info2.setType("Load Balancer");
list.add(info2);
return list;
......
......@@ -184,6 +184,19 @@ public interface ChoreographyService extends JAXRSService {
* @return list of virtual machines for the enactment engine
*/
@GET
@Path("enactmentEngine/{id}/virtualMachienes")
@Path("enactmentEngine/{id}/virtualMachines")
List<VirtualMachineInfoTO> getEEVmList(@NotNull @PathParam("id") String enactmentEngineKey);
/**
* Returns the enactment engine associated to the choreography
*
* @param enactmentEngineKey enactment engine key
* @param choreographyId choreography id
* @return list of virtual machines for the enactment engine
*/
@GET
@Path("enactmentEngine/{eeId}/{choreographyId}/virtualMachines")
List<VirtualMachineInfoTO> getChoreographyVmList(
@NotNull @PathParam("eeId") String enactmentEngineKey,
@NotNull @PathParam("choreographyId") String choreographyId);
}
......@@ -103,5 +103,10 @@ public class ChoreographyServiceImpl extends AbstractServiceImpl implements Chor
return logic.getEEVmList(enactmentEngineKey);
}
@Override
public List<VirtualMachineInfoTO> getChoreographyVmList(
final String enactmentEngineKey,
final String choreographyId) {
return logic.getChoreographyVmList(enactmentEngineKey, choreographyId);
}
}
......@@ -19,7 +19,7 @@ import eu.chorevolution.idm.common.to.VirtualMachineInfoTO;
import java.io.Serializable;
import java.util.List;
import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
import org.apache.syncope.client.console.panels.ChoreographyVMDirectoryPanel;
import org.apache.syncope.client.console.panels.EEVMDirectoryPanel;
import org.apache.syncope.client.console.rest.AnyObjectRestClient;
import org.apache.syncope.client.console.rest.ChoreographyRestClient;
import org.apache.syncope.client.console.widgets.ResourceWidget;
......@@ -69,7 +69,7 @@ public class EnactmentEngineDetailPage extends BaseExtPage {
resourcesOverview.newChildId(),
"bg-yellow", bundle.virtualMachines, "Virtual Machines", "fa fa-cube"));
resourcesOverview.add(new ResourceWidget(
resourcesOverview.newChildId(), "bg-red", bundle.cpus, "CPU", "fa fa-cogs"));
resourcesOverview.newChildId(), "bg-red", "CPU utilization", bundle.percentageCPU, "fa fa-cogs"));
resourcesOverview.add(new ResourceWidget(
resourcesOverview.newChildId(),
"bg-green", bundle.usedRam, bundle.totalRam, "RAM utilization", bundle.percentageRam, "MB", ""));
......@@ -79,7 +79,7 @@ public class EnactmentEngineDetailPage extends BaseExtPage {
"Storage occupancy", bundle.percentageStorage, "GB", "fa fa-database"));
content.add(resourcesOverview);
content.add(new ChoreographyVMDirectoryPanel("virtualMachinesList", getPageReference(), enactmentEngineKey));
content.add(new EEVMDirectoryPanel("virtualMachinesList", getPageReference(), enactmentEngineKey));
// Re-enable when entilements for this service will be defined
//MetaDataRoleAuthorizationStrategy.authorize(content, ENABLE, CamelEntitlement.ROUTE_LIST);
......@@ -88,12 +88,14 @@ public class EnactmentEngineDetailPage extends BaseExtPage {
private class EEStatisticBundle implements Serializable {
private static final long serialVersionUID = 8740173619471549262L;
private static final long serialVersionUID = 3856101339158216754L;
private int virtualMachines;
private int cpus;
private double percentageCPU;
private int usedRam;
private int totalRam;
......@@ -115,6 +117,8 @@ public class EnactmentEngineDetailPage extends BaseExtPage {
this.usedStorage = 0;
this.totalStorage = 0;
double cpuUtilization = 0;
for (VirtualMachineInfoTO vm: vms) {
this.virtualMachines ++;
this.cpus += vm.getCpuNumber();
......@@ -122,8 +126,11 @@ public class EnactmentEngineDetailPage extends BaseExtPage {
this.totalRam += vm.getTotalRam();
this.usedStorage += vm.getUsedStorage();
this.totalStorage += vm.getTotalStorage();
cpuUtilization += vm.getCpuNumber() * vm.getCpuUtilization();
}
this.percentageCPU = Math.round(100 * (cpuUtilization / Float.valueOf(cpus))) / 100d;
this.percentageRam = Math.round(10000 * (usedRam / Float.valueOf(totalRam))) / 100d;
this.percentageStorage = Math.round(10000 * (usedStorage / Float.valueOf(totalStorage)) / 100d);
}
......
......@@ -25,7 +25,6 @@ import org.apache.syncope.client.console.panels.EnactmentEngineDirectoryPanel;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow.WindowClosedCallback;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.model.Model;
import org.apache.wicket.request.mapper.parameter.PageParameters;
......@@ -53,7 +52,7 @@ public class EnactmentEnginePage extends BaseExtPage {
utilityModal.size(Modal.Size.Large);
utilityModal.addSubmitButton();
utilityModal.setWindowClosedCallback(new WindowClosedCallback() {
/*utilityModal.setWindowClosedCallback(new WindowClosedCallback() {
private static final long serialVersionUID = 2372096723782367810L;
......@@ -62,7 +61,7 @@ public class EnactmentEnginePage extends BaseExtPage {
target.add(content);
utilityModal.show(false);
}
});
});*/
content.add(new AjaxLink("addLink") {
......
/*
* Copyright 2016 The CHOReVOLUTION project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.syncope.client.console.panels;
import java.io.Serializable;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPasswordFieldPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
import org.apache.wicket.PageReference;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.Model;
public abstract class AbstractEnactmentEngineModalPanel extends AbstractModalPanel<Serializable> {
private static final long serialVersionUID = 1570261203472359825L;
protected final BaseModal<Serializable> modal;
protected final FieldPanel<String> nameInput;
protected final FieldPanel<String> usernameInput;
protected final FieldPanel<String> passwordInput;
protected final FieldPanel<String> urlInput;
public AbstractEnactmentEngineModalPanel(
final BaseModal<Serializable> modal,
final PageReference pageRef) {
super(modal, pageRef);
this.modal = modal;
final WebMarkupContainer container = new WebMarkupContainer("container");
container.setOutputMarkupId(true);
add(container);
final Form<String> form = new Form<>("AddEEForm");
form.setMarkupId("AddEEForm");
form.setOutputMarkupId(true);
container.add(form);
this.nameInput = new AjaxTextFieldPanel("name", "Name", new Model<>(), true);
nameInput.setRequired(true);
nameInput.addRequiredLabel();
form.add(nameInput);
this.usernameInput = new AjaxTextFieldPanel("username", "Username", new Model<>(), true);
usernameInput.setRequired(true);
usernameInput.addRequiredLabel();
form.add(usernameInput);
this.passwordInput = new AjaxPasswordFieldPanel("password", "Password", new Model<>(), true);
passwordInput.setRequired(true);
passwordInput.addRequiredLabel();
form.add(passwordInput);
this.urlInput = new AjaxTextFieldPanel("url", "Base URL", new Model<>(), true);
urlInput.setRequired(true);
urlInput.addRequiredLabel();
form.add(urlInput);
}
}
......@@ -22,65 +22,22 @@ import org.apache.syncope.client.console.commons.Constants;
import org.apache.syncope.client.console.pages.BasePage;
import static org.apache.syncope.client.console.panels.AbstractModalPanel.LOG;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPasswordFieldPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.Model;
public class AddEnactmentEngineModalPanel extends AbstractModalPanel<Serializable> {
private static final long serialVersionUID = 1570261203472359825L;
private final BaseModal<Serializable> addEEModal;
private final FieldPanel<String> usernameInput;
private final FieldPanel<String> passwordInput;
private final FieldPanel<String> urlInput;
public AddEnactmentEngineModalPanel(
final BaseModal<Serializable> modal,
final PageReference pageRef) {
public class AddEnactmentEngineModalPanel extends AbstractEnactmentEngineModalPanel {
public AddEnactmentEngineModalPanel(final BaseModal<Serializable> modal, final PageReference pageRef) {
super(modal, pageRef);
this.addEEModal = modal;
final WebMarkupContainer container = new WebMarkupContainer("container");
container.setOutputMarkupId(true);
add(container);
final Form<String> form = new Form<>("AddEEForm");
form.setMarkupId("AddEEForm");
form.setOutputMarkupId(true);