You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openaz.apache.org by pd...@apache.org on 2016/03/17 02:06:59 UTC

[20/23] incubator-openaz git commit: Ported original att source to openaz

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/ObadviceDictionary.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/ObadviceDictionary.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/ObadviceDictionary.java
new file mode 100644
index 0000000..1b1edd4
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/ObadviceDictionary.java
@@ -0,0 +1,347 @@
+/*
+ *  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 org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.XacmlAdminAuthorization;
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.jpa.Obadvice;
+import org.apache.openaz.xacml.admin.view.windows.ObadviceEditorWindow;
+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.data.util.filter.Compare;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+
+public class ObadviceDictionary 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 ComboBox comboBoxFilter;
+	@AutoGenerated
+	private Button buttonClone;
+	@AutoGenerated
+	private Button buttonRemove;
+	@AutoGenerated
+	private Button buttonNew;
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(ObadviceDictionary.class);
+	private final ObadviceDictionary self = this;
+	
+	private static final Object[] visibleColumns = new Object[] { "type", "xacmlId", "description", "fulfillOn", "modifiedBy", "modifiedDate", "createdBy", "createdDate"};
+	private static final String[] columnHeaders = new String[] { "Type", "Attribute ID", "Description", "FulFill/Apply", "Modified By", "Modified Date", "Created By", "Created Date"};
+	
+	private final JPAContainer<Obadvice>	obadvice  = new JPAContainer<Obadvice>(Obadvice.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.
+	 * @param jpaContainer 
+	 */
+	public ObadviceDictionary() {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Setup container
+		//
+		boolean isReadOnly;
+		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+				XacmlAdminAuthorization.AdminAction.ACTION_WRITE, 
+				XacmlAdminAuthorization.AdminResource.RESOURCE_DICTIONARIES)) {
+			if (logger.isDebugEnabled()) {
+				logger.debug("write access");
+			}
+			isReadOnly = false;
+			this.obadvice.setEntityProvider(new CachingMutableLocalEntityProvider<Obadvice>(Obadvice.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+		} else {
+			if (logger.isDebugEnabled()) {
+				logger.debug("read only access");
+			}
+			isReadOnly = true;
+			this.obadvice.setEntityProvider(new CachingLocalEntityProvider<Obadvice>(Obadvice.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+		}
+		//
+		// initialize
+		//
+		this.initializeTable(isReadOnly);
+		this.initializeButtons(isReadOnly);
+		this.initializeCombo();
+	}
+	
+	protected void initializeTable(boolean isReadOnly) {
+		//
+		// Set our container
+		//
+		this.table.setContainerDataSource(this.obadvice);
+		//
+		// Initialize GUI properties
+		//
+		this.table.setVisibleColumns(visibleColumns);
+		this.table.setColumnHeaders(columnHeaders);
+		this.table.setImmediate(true);
+		this.table.setColumnCollapsingAllowed(true);
+		//
+		// Is read only
+		//
+		if (isReadOnly) {
+			return;
+		}
+		this.table.setSelectable(true);
+		//
+		// Respond to selections
+		//
+		this.table.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.buttonRemove.setEnabled(self.table.getValue() != null);
+				self.buttonClone.setEnabled(self.table.getValue() != null);
+			}			
+		});
+	}
+	
+	protected void initializeButtons(boolean isReadOnly) {
+		if (isReadOnly) {
+			this.buttonNew.setVisible(false);
+			this.buttonRemove.setVisible(false);
+			this.buttonClone.setVisible(false);
+			return;
+		}
+		//
+		// NEW button
+		//
+		this.buttonNew.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				//
+				// Create window
+				//
+				String domain = XacmlAdminUI.getDomain();
+				String userid = ((XacmlAdminUI)UI.getCurrent()).getUserid();
+				final Obadvice oa = new Obadvice(domain, userid);
+				final EntityItem<Obadvice> entity = self.obadvice.createEntityItem(oa);
+				final ObadviceEditorWindow editor = new ObadviceEditorWindow(entity);
+				editor.setCaption("Add New Obligation/Advice");
+				editor.setCloseShortcut(KeyCode.ESCAPE);
+				editor.setModal(true);
+				editor.addCloseListener(new CloseListener() {
+					private static final long serialVersionUID = 1L;
+
+					@Override
+					public void windowClose(CloseEvent e) {
+						if (editor.isSaved()) {
+							self.obadvice.addEntity(oa);
+							logger.info("Added new obligation/advice: " + oa);
+						}
+					}
+				});
+				editor.center();
+				UI.getCurrent().addWindow(editor);
+			}
+		});
+		//
+		// Disable remove/clone buttons to start
+		//
+		this.buttonRemove.setEnabled(false);
+		this.buttonClone.setEnabled(false);
+		//
+		// REMOVE button
+		//
+		this.buttonRemove.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.obadvice.removeItem(self.table.getValue());
+			}
+		});
+		//
+		// CLONE button
+		//
+		this.buttonClone.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				// TODO
+			}
+		});
+	}
+	
+	protected void initializeCombo() {
+		//
+		// Add filter values
+		//
+		this.comboBoxFilter.addItem(Obadvice.OBLIGATION);
+		this.comboBoxFilter.addItem(Obadvice.ADVICE);
+		//
+		// Initialize GUI properties
+		//
+		this.comboBoxFilter.setImmediate(true);
+		this.comboBoxFilter.setNullSelectionAllowed(true);
+		//
+		//
+		this.comboBoxFilter.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				//
+				// Remove filters
+				//
+				self.obadvice.removeAllContainerFilters();
+				//
+				// What was selected?
+				//
+				Object id = self.comboBoxFilter.getValue();
+				if (id != null) {
+					//
+					// Add filter
+					//
+					if (id.equals(Obadvice.OBLIGATION)) {
+						self.obadvice.addContainerFilter(new Compare.Equal("type", Obadvice.OBLIGATION));
+					} else if (id.equals(Obadvice.ADVICE)) {
+						self.obadvice.addContainerFilter(new Compare.Equal("type", Obadvice.ADVICE));
+					}
+				}
+			}
+		});
+	}
+
+	public void refreshContainer() {
+		this.obadvice.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);
+		
+		// table
+		table = new Table();
+		table.setImmediate(true);
+		table.setWidth("-1px");
+		table.setHeight("-1px");
+		mainLayout.addComponent(table);
+		
+		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);
+		
+		// buttonNew
+		buttonNew = new Button();
+		buttonNew.setCaption("New");
+		buttonNew.setImmediate(true);
+		buttonNew
+				.setDescription("Add a new advice or obligation to the dictionary.");
+		buttonNew.setWidth("-1px");
+		buttonNew.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonNew);
+		horizontalLayoutToolbar.setComponentAlignment(buttonNew, new Alignment(
+				24));
+		
+		// buttonRemove
+		buttonRemove = new Button();
+		buttonRemove.setCaption("Remove");
+		buttonRemove.setImmediate(true);
+		buttonRemove
+				.setDescription("Remove the selected advice or obligation from the dictionary.");
+		buttonRemove.setWidth("-1px");
+		buttonRemove.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonRemove);
+		horizontalLayoutToolbar.setComponentAlignment(buttonRemove,
+				new Alignment(24));
+		
+		// buttonClone
+		buttonClone = new Button();
+		buttonClone.setCaption("Clone");
+		buttonClone.setImmediate(true);
+		buttonClone.setDescription("Clone the selected obligation/advice.");
+		buttonClone.setWidth("-1px");
+		buttonClone.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonClone);
+		horizontalLayoutToolbar.setComponentAlignment(buttonClone,
+				new Alignment(24));
+		
+		// comboBoxFilter
+		comboBoxFilter = new ComboBox();
+		comboBoxFilter.setCaption("Filter By Type");
+		comboBoxFilter.setImmediate(false);
+		comboBoxFilter.setWidth("-1px");
+		comboBoxFilter.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(comboBoxFilter);
+		
+		return horizontalLayoutToolbar;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PDPManagement.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PDPManagement.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PDPManagement.java
new file mode 100644
index 0000000..56fd9cd
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PDPManagement.java
@@ -0,0 +1,862 @@
+/*
+ *  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;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PIPManagement.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PIPManagement.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PIPManagement.java
new file mode 100644
index 0000000..c25f018
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PIPManagement.java
@@ -0,0 +1,538 @@
+/*
+ *  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;
+	}
+
+}