blob: c25f018d7c3bb775ffd0e273ca148e9095746b30 [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.io.FileInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Properties;
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.jpa.PIPConfiguration;
import org.apache.openaz.xacml.admin.util.AdminNotification;
import org.apache.openaz.xacml.admin.view.components.PIPResolverComponent;
import org.apache.openaz.xacml.admin.view.windows.PIPConfigurationEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.PIPImportWindow;
import com.vaadin.addon.jpacontainer.EntityItem;
import com.vaadin.addon.jpacontainer.JPAContainer;
import com.vaadin.addon.jpacontainer.provider.CachingLocalEntityProvider;
import com.vaadin.addon.jpacontainer.provider.CachingMutableLocalEntityProvider;
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.ui.AbstractSelect.ItemCaptionMode;
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.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 PIPManagement extends CustomComponent {
/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
@AutoGenerated
private VerticalLayout mainLayout;
@AutoGenerated
private Table tablePIP;
@AutoGenerated
private HorizontalLayout horizontalLayoutToolbar;
@AutoGenerated
private Button buttonImport;
@AutoGenerated
private Button buttonRemove;
@AutoGenerated
private Button buttonClone;
@AutoGenerated
private Button buttonAdd;
/**
*
*/
private static final long serialVersionUID = 1L;
private static final Log logger = LogFactory.getLog(PIPManagement.class);
private static final Object[] visibleColumns = new Object[] { "name", "description", "piptype", "issuer"};
private static final String[] columnHeaders = new String[] { "Name", "Description", "Type", "Issuer"};
private final Action ADD_CONFIGURATION = new Action("Add Configuration");
private final Action EDIT_CONFIGURATION = new Action("Edit Configuration");
private final Action CLONE_CONFIGURATION = new Action("Clone Configuration");
private final Action REMOVE_CONFIGURATION = new Action("Remove Configuration");
private final Action ADD_RESOLVER = new Action("Add Resolver");
private final Action PUBLISH_CONFIGURATION = new Action("Publish Configuration");
private final PIPManagement self = this;
private final JPAContainer<PIPConfiguration> container = new JPAContainer<PIPConfiguration>(PIPConfiguration.class);
/**
* 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 PIPManagement() {
buildMainLayout();
setCompositionRoot(mainLayout);
//
// Setup containers
//
boolean isReadOnly;
if (((XacmlAdminUI)UI.getCurrent()).isAuthorized(
XacmlAdminAuthorization.AdminAction.ACTION_WRITE,
XacmlAdminAuthorization.AdminResource.RESOURCE_PIP_ADMIN)) {
//
// Writable container
//
container.setEntityProvider(new CachingMutableLocalEntityProvider<PIPConfiguration>(PIPConfiguration.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
isReadOnly = false;
} else {
//
// Read only container
//
container.setEntityProvider(new CachingLocalEntityProvider<PIPConfiguration>(PIPConfiguration.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
isReadOnly = true;
}
//
// Finish initialization
//
this.initializeTree(isReadOnly);
this.initializeButtons(isReadOnly);
//
// Setup
//
this.setupButtons();
}
protected void initializeTree(boolean isReadOnly) {
//
// Initialize GUI properties
//
this.tablePIP.setImmediate(true);
this.tablePIP.setContainerDataSource(this.container);
this.tablePIP.setItemCaptionMode(ItemCaptionMode.PROPERTY);
this.tablePIP.setItemCaptionPropertyId("name");
this.tablePIP.setVisibleColumns(visibleColumns);
this.tablePIP.setColumnHeaders(columnHeaders);
this.tablePIP.setSizeFull();
//
// Access?
//
if (isReadOnly) {
if (logger.isDebugEnabled()) {
logger.debug("read only pip access");
}
return;
}
this.tablePIP.setSelectable(true);
//
// Setup click handler
//
this.tablePIP.addItemClickListener(new ItemClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void itemClick(ItemClickEvent event) {
if (event.isDoubleClick()) {
PIPManagement.editConfiguration(self.container.getItem(event.getItemId()));
}
}
});
//
// Setup action handler
//
this.tablePIP.addActionHandler(new Handler() {
private static final long serialVersionUID = 1L;
@Override
public Action[] getActions(Object target, Object sender) {
if (target == null) {
return new Action[] {ADD_CONFIGURATION};
}
//
// Target is an Object ID
//
EntityItem<PIPConfiguration> config = self.container.getItem(target);
if (config != null && config.getEntity().isReadOnly() == false) {
if (config.getEntity().requiresResolvers()) {
return new Action[] {EDIT_CONFIGURATION, CLONE_CONFIGURATION, REMOVE_CONFIGURATION, PUBLISH_CONFIGURATION, ADD_RESOLVER};
} else {
return new Action[] {EDIT_CONFIGURATION, CLONE_CONFIGURATION, REMOVE_CONFIGURATION, PUBLISH_CONFIGURATION};
}
}
if (logger.isDebugEnabled()) {
logger.debug("Could not find item: " + target);
}
return null;
}
@Override
public void handleAction(Action action, Object sender, Object target) {
EntityItem<PIPConfiguration> config = self.container.getItem(target);
if (config == null) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find item: " + target);
}
return;
}
if (action == ADD_CONFIGURATION) {
PIPManagement.editConfiguration(self.container.createEntityItem(new PIPConfiguration()));
return;
}
if (action == EDIT_CONFIGURATION) {
PIPManagement.editConfiguration(config);
return;
}
if (action == CLONE_CONFIGURATION) {
self.cloneConfiguration(config);
return;
}
if (action == REMOVE_CONFIGURATION) {
self.removeConfiguration(config);
return;
}
if (action == ADD_RESOLVER) {
PIPResolverComponent.addResolver(config.getEntity(), null);
return;
}
if (action == PUBLISH_CONFIGURATION) {
PIPResolverComponent.publishConfiguration(config);
return;
}
}
});
//
// When a selection changes listener
//
this.tablePIP.addValueChangeListener(new ValueChangeListener() {
private static final long serialVersionUID = 1L;
@Override
public void valueChange(ValueChangeEvent event) {
self.setupButtons();
}
});
this.tablePIP.addGeneratedColumn("description", new ColumnGenerator() {
private static final long serialVersionUID = 1L;
@Override
public Object generateCell(Table source, Object itemId, Object columnId) {
EntityItem<PIPConfiguration> entity = self.container.getItem(itemId);
if (entity != null && entity.getEntity() != null) {
TextArea area = new TextArea();
area.setValue(entity.getEntity().getDescription());
area.setNullRepresentation("");
area.setSizeFull();
area.setReadOnly(true);
return area;
}
return null;
}
});
this.tablePIP.addGeneratedColumn("piptype", new ColumnGenerator() {
private static final long serialVersionUID = 1L;
@Override
public Object generateCell(Table source, Object itemId, Object columnId) {
EntityItem<PIPConfiguration> entity = self.container.getItem(itemId);
if (entity != null && entity.getEntity() != null) {
return entity.getEntity().getPiptype().getType();
}
return null;
}
});
//
// Customize the resolver column
//
this.tablePIP.addGeneratedColumn("Resolvers", new ColumnGenerator() {
private static final long serialVersionUID = 1L;
@Override
public Object generateCell(Table source, Object itemId, Object columnId) {
EntityItem<PIPConfiguration> entity = self.container.getItem(itemId);
if (entity != null && entity.getEntity() != null && entity.getEntity().requiresResolvers()) {
PIPResolverComponent component = new PIPResolverComponent(entity.getEntity());
return component;
}
return null;
}
});
}
protected void initializeButtons(boolean isReadOnly) {
if (isReadOnly) {
this.buttonAdd.setVisible(false);
this.buttonRemove.setVisible(false);
this.buttonClone.setVisible(false);
return;
}
this.buttonAdd.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
PIPManagement.editConfiguration(self.container.createEntityItem(new PIPConfiguration()));
}
});
this.buttonRemove.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
self.removeConfiguration(self.container.getItem(self.tablePIP.getValue()));
}
});
this.buttonClone.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
self.cloneConfiguration(self.container.getItem(self.tablePIP.getValue()));
}
});
this.buttonImport.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
final PIPImportWindow window = new PIPImportWindow();
window.setCaption("Import PIP Configuration");
window.setModal(true);
window.center();
window.addCloseListener(new CloseListener() {
private static final long serialVersionUID = 1L;
@Override
public void windowClose(CloseEvent e) {
String file = window.getUploadedFile();
if (file == null) {
return;
}
self.importConfiguration(file);
}
});
UI.getCurrent().addWindow(window);
}
});
}
protected void importConfiguration(String file) {
Properties properties = new Properties();
try {
properties.load(new FileInputStream(file));
Collection<PIPConfiguration> configs = PIPConfiguration.importPIPConfigurations(properties);
if (configs == null || configs.isEmpty()) {
AdminNotification.warn("There were no PIP Engine configurations found.");
} else {
for (PIPConfiguration config : configs) {
this.container.addEntity(config);
}
}
} catch (IOException e) {
String message = "Failed to load properties: " + e.getLocalizedMessage();
logger.error(message);
AdminNotification.error(message);
}
}
public static void editConfiguration(final EntityItem<PIPConfiguration> entity) {
final PIPConfigurationEditorWindow editor = new PIPConfigurationEditorWindow(entity);
if (entity.isPersistent()) {
editor.setCaption("Edit PIP Configuration " + entity.getEntity().getName());
} else {
editor.setCaption("Create New PIP Configuration");
}
editor.setModal(true);
editor.addCloseListener(new CloseListener() {
private static final long serialVersionUID = 1L;
@Override
public void windowClose(CloseEvent event) {
if (editor.isSaved()) {
if (entity.isPersistent() == false) {
((XacmlAdminUI)UI.getCurrent()).getPIPConfigurations().addEntity(entity.getEntity());
}
((XacmlAdminUI)UI.getCurrent()).refreshPIPConfiguration();
}
}
});
editor.center();
UI.getCurrent().addWindow(editor);
}
protected void removeConfiguration(final EntityItem<PIPConfiguration> entity) {
//
// Sanity checks
//
if (entity == null || entity.getEntity() == null) {
logger.error("Removing a null entity");
return;
}
String message = "Are you sure you want to remove the " + entity.getEntity().getName() + " configuration?";
ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm PIP Configuration Deletion", message, "Remove", "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()) {
if (self.container.removeItem(entity.getItemId()) == false) {
logger.warn("Failed to remove PIP configuration");
AdminNotification.warn("Failed to remove PIP configuration.");
} else {
self.setupButtons();
}
}
}
}, true);
}
protected void cloneConfiguration(final EntityItem<PIPConfiguration> entity) {
//
// Sanity checks
//
if (entity == null || entity.getEntity() == null) {
logger.warn("Cloning a null entity, the buttons were not reset. Resetting them.");
this.setupButtons();
return;
}
//
// Clone it
//
PIPManagement.editConfiguration(this.container.createEntityItem(new PIPConfiguration(entity.getEntity(), ((XacmlAdminUI)UI.getCurrent()).getUserid())));
}
protected void setupButtons() {
if (this.tablePIP.getValue() != null) {
Object id = this.tablePIP.getValue();
EntityItem<PIPConfiguration> entity = this.container.getItem(id);
if (entity == null || entity.getEntity().isReadOnly()) {
this.buttonRemove.setEnabled(false);
this.buttonClone.setEnabled(false);
} else {
this.buttonRemove.setEnabled(true);
this.buttonClone.setEnabled(true);
}
} else {
this.buttonRemove.setEnabled(false);
this.buttonClone.setEnabled(false);
}
}
public void refreshContainer() {
this.container.refresh();
}
@AutoGenerated
private VerticalLayout buildMainLayout() {
// common part: create layout
mainLayout = new VerticalLayout();
mainLayout.setImmediate(false);
mainLayout.setWidth("100%");
mainLayout.setHeight("-1px");
mainLayout.setMargin(true);
mainLayout.setSpacing(true);
// top-level component properties
setWidth("100.0%");
setHeight("-1px");
// horizontalLayoutToolbar
horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
mainLayout.addComponent(horizontalLayoutToolbar);
// tablePIP
tablePIP = new Table();
tablePIP.setCaption("PIP Configurations");
tablePIP.setImmediate(false);
tablePIP.setWidth("100.0%");
tablePIP.setHeight("-1px");
mainLayout.addComponent(tablePIP);
return mainLayout;
}
@AutoGenerated
private HorizontalLayout buildHorizontalLayoutToolbar() {
// common part: create layout
horizontalLayoutToolbar = new HorizontalLayout();
horizontalLayoutToolbar.setImmediate(false);
horizontalLayoutToolbar.setWidth("-1px");
horizontalLayoutToolbar.setHeight("-1px");
horizontalLayoutToolbar.setMargin(false);
horizontalLayoutToolbar.setSpacing(true);
// buttonAdd
buttonAdd = new Button();
buttonAdd.setCaption("Add Configuration");
buttonAdd.setImmediate(true);
buttonAdd.setWidth("-1px");
buttonAdd.setHeight("-1px");
horizontalLayoutToolbar.addComponent(buttonAdd);
// buttonClone
buttonClone = new Button();
buttonClone.setCaption("Clone Configuration");
buttonClone.setImmediate(true);
buttonClone.setWidth("-1px");
buttonClone.setHeight("-1px");
horizontalLayoutToolbar.addComponent(buttonClone);
// buttonRemove
buttonRemove = new Button();
buttonRemove.setCaption("Remove Configuration");
buttonRemove.setImmediate(true);
buttonRemove.setWidth("-1px");
buttonRemove.setHeight("-1px");
horizontalLayoutToolbar.addComponent(buttonRemove);
// buttonImport
buttonImport = new Button();
buttonImport.setCaption("Import Configuration");
buttonImport.setImmediate(false);
buttonImport
.setDescription("Imports a configuration from a properties file.");
buttonImport.setWidth("-1px");
buttonImport.setHeight("-1px");
horizontalLayoutToolbar.addComponent(buttonImport);
return horizontalLayoutToolbar;
}
}