blob: 56fd9cd0c2076d1f98103364f733ba55fe2d95cb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.openaz.xacml.admin.components;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.vaadin.dialogs.ConfirmDialog;
import org.vaadin.dialogs.ConfirmDialog.ContentMode;
import org.apache.openaz.xacml.admin.XacmlAdminAuthorization;
import org.apache.openaz.xacml.admin.XacmlAdminUI;
import org.apache.openaz.xacml.admin.model.PDPContainer;
import org.apache.openaz.xacml.admin.model.PDPGroupContainer;
import org.apache.openaz.xacml.admin.model.PDPPIPContainer;
import org.apache.openaz.xacml.admin.model.PDPPolicyContainer;
import org.apache.openaz.xacml.admin.util.AdminNotification;
import org.apache.openaz.xacml.admin.view.windows.EditPDPGroupWindow;
import org.apache.openaz.xacml.admin.view.windows.EditPDPWindow;
import org.apache.openaz.xacml.admin.view.windows.PDPStatusWindow;
import org.apache.openaz.xacml.admin.view.windows.SelectPDPGroupWindow;
import org.apache.openaz.xacml.api.pap.PAPEngine;
import org.apache.openaz.xacml.api.pap.PAPException;
import org.apache.openaz.xacml.api.pap.PDP;
import org.apache.openaz.xacml.api.pap.PDPGroup;
import org.apache.openaz.xacml.api.pap.PDPGroupStatus;
import org.apache.openaz.xacml.api.pap.PDPStatus;
import org.apache.openaz.xacml.std.pap.StdPDPGroup;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.ColumnGenerator;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window.CloseEvent;
import com.vaadin.ui.Window.CloseListener;
public class PDPManagement extends CustomComponent {
/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
@AutoGenerated
private VerticalLayout mainLayout;
@AutoGenerated
private Table table;
@AutoGenerated
private HorizontalLayout horizontalLayoutToolbar;
@AutoGenerated
private Button buttonRemove;
@AutoGenerated
private Button buttonCreate;
private static final long serialVersionUID = 1L;
private final PDPManagement self = this;
private static final Log logger = LogFactory.getLog(PDPManagement.class);
private PDPGroupContainer container;
private static final Action CREATE_GROUP = new Action ("Create Group");
private static final Action REPAIR_GROUP = new Action ("Repair Group");
private static final Action EDIT_GROUP = new Action ("Edit Group");
private static final Action DELETE_GROUP = new Action ("Delete Group");
private static final Action SYNCHRONIZE = new Action ("Synchronize");
private static final Action MAKE_DEFAULT = new Action ("Make Default");
private static final Action CREATE_PDP = new Action ("Create PDP");
private static final Action EDIT_PDP = new Action ("Edit PDP");
private static final Action DELETE_PDP = new Action ("Delete PDP");
private static final Action MOVE_PDP = new Action ("Move PDP");
private static final Action GET_PDP_STATUS = new Action ("View Status");
private PAPEngine papEngine;
/**
* The constructor should first build the main layout, set the
* composition root and then do any custom initialization.
*
* The constructor will not be automatically regenerated by the
* visual editor.
*/
public PDPManagement(PAPEngine engine) {
buildMainLayout();
setCompositionRoot(mainLayout);
//
// Initialize
//
this.papEngine = engine;
//
// Initialize
//
this.initialize();
//
// setup the buttons
//
this.setupButtons();
}
protected void initialize() {
//
// Don't create a container if the engine doesn't exist
//
if (this.papEngine == null) {
//
// remove all the components
//
this.mainLayout.removeAllComponents();
//
// Add a label
//
this.mainLayout.addComponent(new Label("PDP Management unavailable - PAP servlet unavailable."));
//
// done
//
return;
}
//
// Create our container
//
this.container = new PDPGroupContainer(this.papEngine);
//
// Determine authorization level
//
boolean isAdmin = ((XacmlAdminUI)UI.getCurrent()).isAuthorized(
XacmlAdminAuthorization.AdminAction.ACTION_ADMIN,
XacmlAdminAuthorization.AdminResource.RESOURCE_PDP_ADMIN);
try {
this.initializeTree(isAdmin);
this.initializeButtons(isAdmin);
} catch (Exception e) {
logger.error("UNABLE TO START PDPManagement: " + e, e);
// check if PAP servlet is up
try {
Set<PDPGroup> groups = this.papEngine.getPDPGroups();
if (groups == null) {
throw new PAPException("PAP not running");
}
} catch (PAPException | NullPointerException e1) {
setCompositionRoot(new Label("Cannot use PDP Management because the PAP servlet was not running when Admin Console Servlet first initialized."));
return;
}
setCompositionRoot(new Label("Cannot use PDP Management because of error during initialization: " + e.getMessage()));
}
}
protected void initializeTree(final boolean isAdmin) {
//
// Set the data source
//
this.table.setContainerDataSource(this.container);
//
// Setup the GUI properties
//
this.table.setVisibleColumns("Name", "Description", "Status", "Default", "PDPs", "Policies", "PIP Configurations");
this.table.setColumnHeaders("Name", "Description", "Status", "Default", "PDP's", "Policies", "PIP Configurations");
//
// The description should be a text area
//
this.table.addGeneratedColumn("Description", new ColumnGenerator() {
private static final long serialVersionUID = 1L;
@Override
public Object generateCell(Table source, Object itemId, Object columnId) {
TextArea area = new TextArea();
area.setValue(((PDPGroup) itemId).getDescription());
area.setReadOnly(true);
return area;
}
});
//
// Generate a GUI element for the PDP's
//
this.table.addGeneratedColumn("PDPs", new ColumnGenerator() {
private static final long serialVersionUID = 1L;
@Override
public Object generateCell(Table source, Object itemId, Object columnId) {
final Table table = new Table();
final PDPContainer container = new PDPContainer((PDPGroup) itemId);
//
// Setup the container data
//
table.setContainerDataSource(container);
//
// Save the group for easy access
//
table.setData(itemId);
//
// GUI properties
//
table.setPageLength(table.getContainerDataSource().size() + 2);
table.setVisibleColumns("Name", "Status", "Description");
table.setColumnCollapsingAllowed(true);
table.setColumnCollapsed("Description", true);
table.setWidth("100%");
//
// If an admin, then it is editable
//
if (isAdmin) {
//
// Set it as selectable
//
table.setSelectable(true);
//
// Add actions
//
table.addActionHandler(new Handler() {
private static final long serialVersionUID = 1L;
@Override
public Action[] getActions(Object target, Object sender) {
if (target == null) {
return new Action[] {CREATE_PDP};
}
if (target instanceof PDP) {
if (self.container.size() > 1) {
return new Action[] {EDIT_PDP, GET_PDP_STATUS, MOVE_PDP, DELETE_PDP};
} else {
return new Action[] {EDIT_PDP, GET_PDP_STATUS, DELETE_PDP};
}
}
return null;
}
@Override
public void handleAction(Action action, Object sender, Object target) {
if (action == CREATE_PDP) {
self.editPDP(null, (PDPGroup) table.getData());
return;
}
if (action == EDIT_PDP) {
assert target instanceof PDP;
self.editPDP((PDP) target, (PDPGroup) table.getData());
return;
}
if (action == MOVE_PDP) {
assert target instanceof PDP;
self.movePDP((PDP) target, (PDPGroup) table.getData());
return;
}
if (action == DELETE_PDP) {
assert target instanceof PDP;
self.deletePDP((PDP) target, (PDPGroup) table.getData());
return;
}
if (action == GET_PDP_STATUS) {
assert target instanceof PDP;
self.getPDPStatus((PDP) target, (PDPGroup) table.getData());
}
}
});
//
// Respond to events
//
table.addItemClickListener(new ItemClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void itemClick(ItemClickEvent event) {
if (event.isDoubleClick()) {
self.editPDP((PDP) event.getItemId(), (PDPGroup) table.getData());
}
}
});
}
return table;
}
});
//
// Generate a GUI element for the policies
//
this.table.addGeneratedColumn("Policies", new ColumnGenerator() {
private static final long serialVersionUID = 1L;
@Override
public Object generateCell(Table source, Object itemId, Object columnId) {
Table table = new Table();
table.setContainerDataSource(new PDPPolicyContainer((PDPGroup) itemId));
table.setPageLength(table.getContainerDataSource().size() + 2);
table.setVisibleColumns("Root", "Name", "Version", "Description");
table.setColumnCollapsingAllowed(true);
table.setColumnCollapsed("Description", true);
table.setWidth("100%");
return table;
}
});
//
// Generate a GUI element for the PIP configurations
//
this.table.addGeneratedColumn("PIP Configurations", new ColumnGenerator() {
private static final long serialVersionUID = 1L;
@Override
public Object generateCell(Table source, Object itemId, Object columnId) {
Table table = new Table();
if (itemId instanceof PDPGroup) {
table.setContainerDataSource(new PDPPIPContainer((PDPGroup) itemId));
table.setPageLength(table.getContainerDataSource().size() + 2);
}
if (itemId instanceof PDP) {
table.setContainerDataSource(new PDPPIPContainer((PDP) itemId));
table.setVisible(false);
table.setPageLength(0);
}
table.setVisibleColumns("Name", "Description");
table.setColumnCollapsingAllowed(true);
table.setColumnCollapsed("Description", true);
table.setWidth("100%");
return table;
}
});
//
// Check the user's authorization level
//
if (((XacmlAdminUI)UI.getCurrent()).isAuthorized(
XacmlAdminAuthorization.AdminAction.ACTION_ADMIN,
XacmlAdminAuthorization.AdminResource.RESOURCE_PDP_ADMIN)) {
this.table.setSelectable(true);
} else {
if (logger.isDebugEnabled()) {
logger.debug("No admin access to pdp management");
}
return;
}
//
// Setup Action Handlers
//
this.table.addActionHandler(new Handler() {
private static final long serialVersionUID = 1L;
@Override
public Action[] getActions(Object target, Object sender) {
if (target == null) {
//
// Nothing is selected, they right-clicked empty space.
// Only one action.
//
return new Action[] {CREATE_GROUP};
}
if (target instanceof PDPGroup) {
List<Action> actions = new ArrayList<Action>();
PDPGroupStatus.Status status = ((PDPGroup)target).getStatus().getStatus();
if (status == PDPGroupStatus.Status.LOAD_ERRORS) {
actions.add(REPAIR_GROUP);
}
if (((PDPGroup)target).isDefaultGroup() == false) {
actions.add(MAKE_DEFAULT);
}
actions.add(EDIT_GROUP);
if (status == PDPGroupStatus.Status.OUT_OF_SYNCH) {
actions.add(SYNCHRONIZE);
}
if (((PDPGroup)target).isDefaultGroup() == false) {
actions.add(DELETE_GROUP);
}
actions.add(CREATE_PDP);
// Throws a class cast exception
// return (Action[]) actions.toArray();
Action[] actions2 = new Action[actions.size()];
int index = 0;
for (Action a : actions) {
actions2[index++] = a;
}
return actions2;
}
return null;
}
@Override
public void handleAction(Action action, Object sender, Object target) {
if (action == CREATE_GROUP) {
self.editPDPGroup(null);
return;
}
if (action == EDIT_GROUP) {
assert target instanceof PDPGroup;
self.editPDPGroup((PDPGroup) target);
return;
}
if (action == DELETE_GROUP) {
self.deleteGroup((PDPGroup) target);
return;
}
if (action == REPAIR_GROUP) {
if (target instanceof PDPGroup) {
((PDPGroup) target).repair();
} else {
String message = "Action '" + REPAIR_GROUP.getCaption() + "' called on non-group target '" + target + "'";
logger.error(message);
AdminNotification.error(message);
}
return;
}
if (action == MAKE_DEFAULT) {
if (target instanceof PDPGroup) {
try {
self.container.makeDefault((PDPGroup) target);
} catch (Exception e) {
AdminNotification.error("Make Default failed. Reason:\n" + e.getMessage());
}
} else {
String message = "Action '" + MAKE_DEFAULT.getCaption() + "' called on non-group target '" + target + "'";
logger.error(message);
AdminNotification.error(message);
}
return;
}
if (action == SYNCHRONIZE) {
if (target instanceof PDPGroup) {
logger.error("SYNCHRONIZE NOT YET IMPLMENTED");
AdminNotification.error("Synchronize not yet implemented");
} else {
String message = "Action '" + SYNCHRONIZE.getCaption() + "' called on non-group target '" + target + "'";
logger.error(message);
AdminNotification.error(message);
}
return;
}
if (action == CREATE_PDP) {
if (target instanceof PDPGroup) {
self.editPDP(null, ((PDPGroup)target));
} else {
String message = "Action '" + CREATE_PDP.getCaption() + "' called on non-group target '" + target + "'";
logger.error(message);
AdminNotification.error(message);
}
return;
}
}
});
//
// Listen for item change notifications
//
this.table.addItemClickListener(new ItemClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void itemClick(ItemClickEvent event) {
if (event.isDoubleClick()) {
assert event.getItemId() instanceof PDPGroup;
self.editPDPGroup((PDPGroup) event.getItemId());
}
}
});
//
// Respond to selection events
//
this.table.addValueChangeListener(new ValueChangeListener() {
private static final long serialVersionUID = 1L;
@Override
public void valueChange(ValueChangeEvent event) {
Object id = self.table.getValue();
if (id == null) {
self.buttonRemove.setEnabled(false);
} else {
//
// Make sure its not the default group
//
if (((PDPGroup) id).isDefaultGroup()) {
self.buttonRemove.setEnabled(false);
} else {
self.buttonRemove.setEnabled(true);
}
}
}
});
//
// Maximize the table
//
this.table.setSizeFull();
}
protected void initializeButtons(final boolean isAdmin) {
if (isAdmin == false) {
return;
}
this.buttonCreate.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
self.editPDPGroup(null);
}
});
this.buttonRemove.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
Object id = self.table.getValue();
assert id != null;
assert id instanceof PDPGroup;
self.deleteGroup((PDPGroup) id);
self.table.select(self.table.getNullSelectionItemId());
}
});
}
protected void setupButtons() {
if (this.table.getValue() == null) {
this.buttonRemove.setEnabled(false);
} else {
this.buttonRemove.setEnabled(true);
}
}
protected void editPDP(final PDP pdp, final PDPGroup group) {
final EditPDPWindow editor = new EditPDPWindow(pdp, this.container.getGroups());
if (pdp == null) {
editor.setCaption("Create New PDP");
} else {
editor.setCaption("Edit PDP " + pdp.getId());
}
editor.setModal(true);
editor.addCloseListener(new CloseListener() {
private static final long serialVersionUID = 1L;
@Override
public void windowClose(CloseEvent event) {
if (editor.isSaved() == false) {
return;
}
try {
//
// Adding a new PDP?
//
if (pdp == null) {
//
// Yes tell the container to add it
//
self.container.addNewPDP(editor.getPDPId(), group, editor.getPDPName(), editor.getPDPDescription());
} else {
//
// No tell the container to update it
//
pdp.setName(editor.getPDPName());
pdp.setDescription(editor.getPDPDescription());
self.container.updatePDP(pdp);
}
} catch (Exception e) {
String message = "Unable to create PDP. Reason:\n" + e.getMessage();
logger.error(message);
AdminNotification.error(message);
}
}
});
editor.center();
UI.getCurrent().addWindow(editor);
}
protected void editPDPGroup(final PDPGroup group) {
//
// copy the group
//
final StdPDPGroup copyGroup = (group == null ? null : new StdPDPGroup(group));
//
//
//
final EditPDPGroupWindow editor = new EditPDPGroupWindow(copyGroup, this.container.getGroups(), papEngine);
if (group == null) {
editor.setCaption("Create PDP Group");
} else {
editor.setCaption("Edit PDP Group " + ((PDPGroup) group).getName());
}
editor.setModal(true);
editor.addCloseListener(new CloseListener() {
private static final long serialVersionUID = 1L;
@Override
public void windowClose(CloseEvent event) {
if (editor.isSaved() == false) {
return;
}
if (group == null) {
//
// Creating a new group
//
try {
self.container.addNewGroup(editor.getGroupName(), editor.getGroupDescription());
} catch (Exception e) {
String message = "Unable to create Group. Reason:\n" + e.getMessage();
logger.error(message);
AdminNotification.error(message);
}
} else {
//
// Update group
//
self.container.updateGroup(editor.getUpdatedObject());
}
}
});
editor.center();
UI.getCurrent().addWindow(editor);
}
protected void deletePDP(final PDP pdp, final PDPGroup pdpGroup) {
String message = "Are you sure you want to delete <B>" + (pdp.getName() == null ? "" : pdp.getName()) + "</B> group?";
ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm PDP Deletion", message, "Delete", "Cancel");
dialog.setContentMode(ContentMode.HTML);
dialog.show(getUI(), new ConfirmDialog.Listener() {
private static final long serialVersionUID = 1L;
@Override
public void onClose(ConfirmDialog dialog) {
if (dialog.isConfirmed()) {
try {
self.container.removePDP(pdp, pdpGroup);
} catch (PAPException e) {
logger.warn("Failed to remove pdp");
AdminNotification.warn("Failed to remove PDP");
}
}
}
}, true);
}
protected void movePDP(final PDP pdp, final PDPGroup currentGroup) {
List<PDPGroup> currentGroups = this.container.getGroups();
Set<PDPGroup> otherGroups = new HashSet<PDPGroup>(currentGroups);
if (otherGroups.remove(currentGroup) == false) {
logger.warn("Group list inconsistency - failed to move pdp to selected group");
return;
}
final SelectPDPGroupWindow editor = new SelectPDPGroupWindow(otherGroups, "What was this?");
editor.setCaption("Move PDP to group");
editor.setModal(true);
editor.addCloseListener(new CloseListener() {
private static final long serialVersionUID = 1L;
@Override
public void windowClose(CloseEvent event) {
if (editor.isSaved()) {
self.container.movePDP((PDP) pdp, editor.selectedGroup());
}
}
});
editor.center();
UI.getCurrent().addWindow(editor);
}
protected void getPDPStatus(final PDP pdp, final PDPGroup group) {
PDPStatus status;
try {
status = papEngine.getStatus(pdp);
} catch (Exception e) {
AdminNotification.error("Unable to get details for pdp '" + pdp.getId() + "' with summary status: " + pdp.getStatus().getStatus());
return;
}
logger.info(status);
PDPStatusWindow window = new PDPStatusWindow(status);
window.setCaption("Status for PDP " + pdp.getName());
window.setModal(true);
window.center();
UI.getCurrent().addWindow(window);
}
private void deleteGroup(final PDPGroup group) {
//
// Cannot be the default group
//
if (group.isDefaultGroup()) {
logger.error("Cannot delete the Default group");
return;
}
//
// Any PDPs in the group?
//
Set<PDP> pdps = group.getPdps();
if (pdps.isEmpty()) {
//
// There are no PDP's, so just prompt to remove it
//
String message = "Are you sure you want to delete <B>" + (group.getName() == null ? "" : group.getName()) + "</B> group?";
ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm Group Deletion", message, "Delete", "Cancel");
dialog.setContentMode(ContentMode.HTML);
dialog.show(getUI(), new ConfirmDialog.Listener() {
private static final long serialVersionUID = 1L;
@Override
public void onClose(ConfirmDialog dialog) {
if (dialog.isConfirmed()) {
try {
self.container.removeGroup(group, null);
} catch (Exception e1) {
logger.warn("Container failed to remove group");
AdminNotification.error("Unable to delete group '" + group.getId() + "'. Reason:\n" + e1.getMessage());
}
return;
}
}
}, true);
return;
}
//
// Get our set of groups
//
List<PDPGroup> currentGroups = this.container.getGroups();
Set<PDPGroup> otherGroups = new HashSet<PDPGroup>(currentGroups);
if (otherGroups.remove(group) == false) {
logger.warn("Group list inconsistency - failed to remove group we are attempting to delete");
return;
}
//
// We should have at least one group
//
if (otherGroups.isEmpty()) {
logger.error("Group list inconsistency - no other groups to choose from.");
return;
}
//
// If there is only one group, it SHOULD be the default group
//
if (otherGroups.size() == 1) {
PDPGroup loneGroup = otherGroups.iterator().next();
if (loneGroup.isDefaultGroup() == false) {
logger.error("Group list inconsistency - lone group is NOT default.");
return;
}
}
//
// Create our confirmation window
//
final SelectPDPGroupWindow window = new SelectPDPGroupWindow(otherGroups, "Select New Group for PDPs");
window.setCaption("Confirm Group " + group.getName() + " Deletion");
window.setCloseShortcut(KeyCode.ESCAPE);
window.setModal(true);
window.addCloseListener(new CloseListener() {
private static final long serialVersionUID = 1L;
@Override
public void windowClose(CloseEvent e) {
if (window.isSaved()) {
PDPGroup newGroup = window.selectedGroup();
if (newGroup == null) {
logger.warn("No group selected for moving PDPs into");
AdminNotification.warn("No group selected for moving PDPs into. Group '" + group.getId() + "' not deleted");
return;
}
try {
self.container.removeGroup(group, newGroup);
} catch (Exception e1) {
logger.warn("Container failed to remove group: " + e1, e1);
AdminNotification.error("Unable to delete group '" + group.getId() + "'. Reason:\n" + e1.getMessage());
}
}
}
});
getUI().addWindow(window);
}
public void refreshContainer() {
if (this.container != null) {
this.container.refreshGroups();
}
}
@AutoGenerated
private VerticalLayout buildMainLayout() {
// common part: create layout
mainLayout = new VerticalLayout();
mainLayout.setImmediate(false);
mainLayout.setWidth("100%");
mainLayout.setHeight("100%");
mainLayout.setMargin(false);
// top-level component properties
setWidth("100.0%");
setHeight("100.0%");
// horizontalLayoutToolbar
horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
mainLayout.addComponent(horizontalLayoutToolbar);
// tree
table = new Table();
table.setImmediate(false);
table.setWidth("-1px");
table.setHeight("-1px");
mainLayout.addComponent(table);
mainLayout.setExpandRatio(table, 1.0f);
return mainLayout;
}
@AutoGenerated
private HorizontalLayout buildHorizontalLayoutToolbar() {
// common part: create layout
horizontalLayoutToolbar = new HorizontalLayout();
horizontalLayoutToolbar.setImmediate(false);
horizontalLayoutToolbar.setWidth("-1px");
horizontalLayoutToolbar.setHeight("-1px");
horizontalLayoutToolbar.setMargin(true);
horizontalLayoutToolbar.setSpacing(true);
// buttonCreate
buttonCreate = new Button();
buttonCreate.setCaption("Create Group");
buttonCreate.setImmediate(false);
buttonCreate.setWidth("-1px");
buttonCreate.setHeight("-1px");
horizontalLayoutToolbar.addComponent(buttonCreate);
// buttonRemove
buttonRemove = new Button();
buttonRemove.setCaption("Remove Group");
buttonRemove.setImmediate(false);
buttonRemove.setWidth("-1px");
buttonRemove.setHeight("-1px");
horizontalLayoutToolbar.addComponent(buttonRemove);
return horizontalLayoutToolbar;
}
}