| /* |
| * 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; |
| } |
| |
| } |