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:43 UTC

[04/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/view/windows/PIPConfigurationEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPConfigurationEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPConfigurationEditorWindow.java
new file mode 100644
index 0000000..08f9306
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPConfigurationEditorWindow.java
@@ -0,0 +1,364 @@
+/*
+ *  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.view.windows;
+
+import java.util.Locale;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.jpa.PIPConfiguration;
+import org.apache.openaz.xacml.admin.jpa.PIPType;
+import org.apache.openaz.xacml.admin.util.JPAUtils;
+import org.apache.openaz.xacml.admin.view.fields.ConfigParamField;
+import com.vaadin.addon.jpacontainer.EntityItem;
+import com.vaadin.addon.jpacontainer.fieldfactory.SingleSelectConverter;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
+import com.vaadin.data.fieldgroup.PropertyId;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.event.FieldEvents.TextChangeEvent;
+import com.vaadin.event.FieldEvents.TextChangeListener;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
+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.CheckBox;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.Window;
+
+public class PIPConfigurationEditorWindow extends Window {
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(PIPConfigurationEditorWindow.class);
+	private final PIPConfigurationEditorWindow self = this;
+	private final EntityItem<PIPConfiguration> entity;
+	private FieldGroup fieldGroup;
+	private boolean isSaved = false;
+	
+	private GridLayout grid = new GridLayout(2,6);
+	
+	@PropertyId("piptype")
+	ComboBox comboType = new ComboBox("Type");
+	
+	@PropertyId("name")
+	TextField fieldName = new TextField("Name");
+	
+	@PropertyId("description")
+	TextArea areaDescription = new TextArea("Description");
+
+	@PropertyId("issuer")
+	TextField fieldIssuer = new TextField("Issuer");
+	
+	@PropertyId("requiresResolvers")
+	CheckBox requiresResolvers = new CheckBox("Requires Resolvers");
+	
+	@PropertyId("pipconfigParams")
+	ConfigParamField paramField = null;
+	
+	Button	buttonSave = new Button("Save");
+	
+	/**
+	 * 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 PIPConfigurationEditorWindow(EntityItem<PIPConfiguration> entity) {
+		//
+		// Our base component
+		//
+		this.setContent(this.grid);
+		this.grid.setMargin(true);
+		this.grid.setSpacing(true);
+		//
+		// Set our shortcuts
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// Save
+		//
+		this.entity = entity;
+		//
+		// Check if a brand new object and set the default
+		// pip type.
+		//
+		if (this.entity.getEntity().getPiptype() == null) {
+			this.entity.getEntity().setPiptype(JPAUtils.getPIPType(PIPType.TYPE_SQL));
+		}
+
+		//
+		// Initialize GUI components
+		//
+		this.initialize();
+		//
+		// Add components
+		//
+		this.grid.addComponent(this.comboType, 0, 0);
+		this.grid.addComponent(this.fieldName, 0, 1);
+		this.grid.addComponent(this.fieldIssuer, 0, 2);
+		this.grid.addComponent(this.areaDescription, 0, 3);
+		this.grid.addComponent(this.requiresResolvers, 0, 4);
+		this.grid.addComponent(this.paramField, 1, 0, 1, 4);
+		this.grid.addComponent(this.buttonSave, 0, 5, 1, 5);
+		//
+		// Bind and initialize
+		//
+		this.initializeFields();
+		//
+		// Post initialize
+		//
+		this.initializeButtons();
+		//
+		// Set focus
+		//
+		this.fieldName.focus();
+		//
+		// Initially call this to see if the entity is already
+		// saveable
+		//
+		this.formChanged();
+	}
+	
+	protected void initialize() {
+		//
+		//
+		//
+		this.fieldName.setImmediate(true);
+		this.fieldName.setNullRepresentation("");
+		this.fieldName.setRequired(true);
+		this.fieldName.setRequiredError("Enter a name for the configuration");
+		this.fieldName.setInputPrompt("Eg. \"Company LDAP Server\" or \"MySQL Customer DB\"");
+
+		this.fieldIssuer.setNullRepresentation("");
+		this.fieldIssuer.setRequired(false);
+		this.fieldIssuer.setInputPrompt("Eg. urn:com:sample:hr");
+		
+		this.areaDescription.setNullRepresentation("");
+		this.areaDescription.setRequired(false);
+		this.areaDescription.setInputPrompt("Optionally write a description for this configuration.");
+		this.areaDescription.setRows(3);
+		this.areaDescription.setWidth("100%");
+		//
+		//
+		//
+		this.requiresResolvers.setConverter(new Converter<Boolean, Object>() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Object convertToModel(Boolean value,
+					Class<? extends Object> targetType, Locale locale)
+					throws Converter.ConversionException {
+				if (targetType.isAssignableFrom(java.lang.Character.class)) {
+					if (value) {
+						return '1';
+					} else {
+						return '0';
+					}
+				}
+				return null;
+			}
+
+			@Override
+			public Boolean convertToPresentation(Object value,
+					Class<? extends Boolean> targetType, Locale locale)
+					throws Converter.ConversionException {
+				if (value instanceof Character) {
+					return ((Character) value) == '1';
+				}
+				return null;
+			}
+
+			@Override
+			public Class<Object> getModelType() {
+				return Object.class;
+			}
+
+			@Override
+			public Class<Boolean> getPresentationType() {
+				return Boolean.class;
+			}
+		});
+		//
+		//
+		//
+		this.comboType.setContainerDataSource(((XacmlAdminUI)UI.getCurrent()).getPIPTypes());
+		this.comboType.setImmediate(true);
+		this.comboType.setConverter(new SingleSelectConverter<Object>(this.comboType));
+		this.comboType.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+		this.comboType.setItemCaptionPropertyId("type");
+		this.comboType.setNullSelectionAllowed(false);
+		this.comboType.setRequired(true);
+		this.comboType.setRequiredError("You need to identify what type of configuration this is.");
+		//
+		//
+		//
+		this.paramField = new ConfigParamField(this.entity);
+		this.paramField.setValidationVisible(false);
+	}
+	
+	protected void initializeFields() {
+		//
+		// Now create our field group and bind our fields.
+		// This will populate the components with the
+		// current value if we are editing an entity.
+		//
+		this.fieldGroup = new FieldGroup(this.entity);
+		this.fieldGroup.bindMemberFields(this);
+		//
+		//
+		//
+		this.fieldName.addTextChangeListener(new TextChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void textChange(TextChangeEvent event) {
+				self.formChanged();
+			}
+			
+		});
+		this.fieldName.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.formChanged();
+			}			
+		});
+		//
+		//
+		//
+		this.paramField.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.formChanged();
+			}			
+		});
+		//
+		// Only custom PIP configurations should be allowed to
+		// check the "requires resolvers" box. We know that the
+		// SQL/LDAP/HyperSQL/CSV resolver already do require resolvers.
+		//
+		if (this.entity.getEntity().getPiptype().isCustom() == false) {
+			this.requiresResolvers.setEnabled(false);
+		}
+		//
+		// Finish GUI intialization
+		//
+		if (this.entity.isPersistent()) {
+			//
+			// The user is editing something, don't let them change
+			// the type
+			//
+			this.comboType.setReadOnly(true);
+		}
+		this.comboType.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				//
+				// Get the new value
+				//
+				Object id = self.comboType.getValue();
+				EntityItem<PIPType> type = null;
+				if (id != null) {
+					type = ((XacmlAdminUI) UI.getCurrent()).getPIPTypes().getItem(id);
+				}
+				//
+				// Have our custom field reset itself
+				//
+				self.paramField.resetContent(type != null ? type.getEntity() : null);
+				//
+				// Do we need to display the requires resolver check box?
+				//
+				if (type != null && type.getEntity().isCustom()) {
+					self.requiresResolvers.setEnabled(true);
+					self.requiresResolvers.setRequired(true);
+					self.requiresResolvers.setValue(self.entity.getEntity().requiresResolvers());
+				} else {
+					self.requiresResolvers.setEnabled(false);
+					self.requiresResolvers.setRequired(false);
+				}
+				//
+				// Re-center the form
+				//
+				self.center();
+				//
+				// Check if we can enable the save button
+				//
+				self.formChanged();
+			}			
+		});
+	}
+		
+	protected void formChanged() {
+		if (this.fieldGroup.isValid() || this.entity.isModified()) {
+			this.buttonSave.setEnabled(true);
+		} else {
+			this.buttonSave.setEnabled(false);
+		}
+	}
+	
+	protected void initializeButtons() {
+		this.grid.setComponentAlignment(this.buttonSave, Alignment.BOTTOM_CENTER);
+		this.buttonSave.setImmediate(true);
+		this.buttonSave.setEnabled(false);
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				try {
+					//
+					// Commit changes
+					//
+					self.fieldGroup.commit();
+					//
+					// Save
+					//
+					self.isSaved = true;
+					//
+					// We can close
+					//
+					self.close();
+				} catch (CommitException e) {
+					logger.warn("Couldn't commit, the save button should NOT be enabled.");
+				}
+			}			
+		});
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPCustomResolverEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPCustomResolverEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPCustomResolverEditorWindow.java
new file mode 100644
index 0000000..e024d0e
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPCustomResolverEditorWindow.java
@@ -0,0 +1,65 @@
+/*
+ *  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.view.windows;
+
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.VerticalLayout;
+
+public class PIPCustomResolverEditorWindow extends CustomComponent {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	/**
+	 * 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 PIPCustomResolverEditorWindow() {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("-1px");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(false);
+		
+		// top-level component properties
+		setWidth("-1px");
+		setHeight("-1px");
+		
+		return mainLayout;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPImportWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPImportWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPImportWindow.java
new file mode 100644
index 0000000..650ed09
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPImportWindow.java
@@ -0,0 +1,116 @@
+/*
+ *  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.view.windows;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.ui.Upload;
+import com.vaadin.ui.Upload.Receiver;
+import com.vaadin.ui.Upload.SucceededEvent;
+import com.vaadin.ui.Upload.SucceededListener;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class PIPImportWindow extends Window implements Receiver, SucceededListener  {
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+	private static final Log logger	= LogFactory.getLog(PolicyUploadWindow.class);
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+
+	@AutoGenerated
+	private Upload upload;
+
+	private static final long serialVersionUID = 1L;
+	private String filename = null;
+	
+	/**
+	 * 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 PIPImportWindow() {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Set ourselves up
+		//
+		this.upload.addSucceededListener(this);
+		this.upload.setReceiver(this);
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("-1px");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(true);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("-1px");
+		setHeight("-1px");
+		
+		// upload_1
+		upload = new Upload();
+		upload.setImmediate(false);
+		upload.setWidth("-1px");
+		upload.setHeight("-1px");
+		mainLayout.addComponent(upload);
+		
+		return mainLayout;
+	}
+
+	@Override
+	public void uploadSucceeded(SucceededEvent event) {
+		this.filename = event.getFilename();
+		this.close();
+	}
+
+	@Override
+	public OutputStream receiveUpload(String filename, String mimeType) {
+		//
+		// Try to create the output stream
+		//
+		try {
+			return new FileOutputStream(filename);
+		} catch (FileNotFoundException e) {
+			logger.error("Failed to create uploaded file", e);
+		}
+		return null;
+	}
+	
+	public String	getUploadedFile() {
+		return this.filename;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPParamEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPParamEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPParamEditorWindow.java
new file mode 100644
index 0000000..70942c2
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPParamEditorWindow.java
@@ -0,0 +1,261 @@
+/*
+ *  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.view.windows;
+
+import org.apache.openaz.xacml.admin.jpa.PIPConfigParam;
+import org.apache.openaz.xacml.admin.jpa.PIPResolverParam;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Buffered.SourceException;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.Validator.InvalidValueException;
+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.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class PIPParamEditorWindow extends Window {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Button buttonSave;
+	@AutoGenerated
+	private TextField textFieldValue;
+	@AutoGenerated
+	private TextField textFieldName;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private final PIPParamEditorWindow self = this;
+	private final Object config;
+	private boolean isSaved = false;
+	
+	/**
+	 * 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 PIPParamEditorWindow(Object config) {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Save parameters
+		//
+		this.config = config;
+		//
+		// Initialize
+		//
+		this.initialize();
+		//
+		// close shortcut
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// focus
+		//
+		this.textFieldName.focus();
+	}
+	
+	protected void initialize() {
+		//
+		// GUI properties
+		//
+		this.textFieldName.setImmediate(true);
+		this.textFieldName.setNullRepresentation("");
+		this.textFieldValue.setImmediate(true);
+		this.textFieldValue.setNullRepresentation("");
+		//
+		// Now setup based on the object
+		//
+		if (this.config instanceof PIPConfigParam) {
+			this.initializePIPConfiguration();
+		} else if (this.config instanceof PIPResolverParam) {
+			this.initializePIPResolver();
+		} else {
+			throw new IllegalArgumentException("Unknown object");
+		}
+		this.initializeButtons();
+		this.setupButtons();
+	}
+	
+	protected void initializePIPConfiguration() {
+		final PIPConfigParam param = (PIPConfigParam) this.config;
+		//
+		// setup the name
+		//
+		this.textFieldName.setValue(param.getParamName());	
+		this.textFieldName.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				param.setParamName(self.textFieldName.getValue());
+				self.setupButtons();
+			}
+		});
+		//
+		// setup the value
+		//
+		this.textFieldValue.setValue(param.getParamValue());	
+		this.textFieldValue.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				param.setParamValue(self.textFieldValue.getValue());
+				self.setupButtons();
+			}
+		});
+	}
+	
+	protected void initializePIPResolver() {
+		final PIPResolverParam param = (PIPResolverParam) this.config;
+		//
+		// setup the name
+		//
+		this.textFieldName.setValue(param.getParamName());	
+		this.textFieldName.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				param.setParamName(self.textFieldName.getValue());
+				self.setupButtons();
+			}
+		});
+		//
+		// setup the value
+		//
+		this.textFieldValue.setValue(param.getParamValue());	
+		this.textFieldValue.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				param.setParamValue(self.textFieldValue.getValue());
+				self.setupButtons();
+			}
+		});
+	}
+	
+	protected void initializeButtons() {
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				try {
+					//
+					// Commit the values
+					//
+					self.textFieldName.commit();
+					self.textFieldValue.commit();
+					//
+					// Done, save
+					//
+					self.isSaved = true;
+					//
+					// Close
+					//
+					self.close();
+				} catch (SourceException | InvalidValueException e) { //NOPMD
+					//
+					// Vaadin will display error
+					//
+				}
+			}
+		});
+	}
+	
+	protected void setupButtons() {
+		if (this.textFieldName.getValue() != null && this.textFieldValue.getValue() != null) {
+			this.buttonSave.setEnabled(true);
+		} else {
+			this.buttonSave.setEnabled(false);
+		}
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public Object getParameter() {
+		return this.config;
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("-1px");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(true);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("-1px");
+		setHeight("-1px");
+		
+		// textFieldName
+		textFieldName = new TextField();
+		textFieldName.setCaption("Parameter Name");
+		textFieldName.setImmediate(false);
+		textFieldName.setWidth("-1px");
+		textFieldName.setHeight("-1px");
+		textFieldName.setInvalidAllowed(false);
+		textFieldName.setRequired(true);
+		mainLayout.addComponent(textFieldName);
+		
+		// textFieldValue
+		textFieldValue = new TextField();
+		textFieldValue.setCaption("Parameter Value");
+		textFieldValue.setImmediate(false);
+		textFieldValue.setWidth("-1px");
+		textFieldValue.setHeight("-1px");
+		textFieldValue.setInvalidAllowed(false);
+		textFieldValue.setRequired(true);
+		mainLayout.addComponent(textFieldValue);
+		
+		// buttonSave
+		buttonSave = new Button();
+		buttonSave.setCaption("Save");
+		buttonSave.setImmediate(true);
+		buttonSave.setWidth("-1px");
+		buttonSave.setHeight("-1px");
+		mainLayout.addComponent(buttonSave);
+		mainLayout.setComponentAlignment(buttonSave, new Alignment(48));
+		
+		return mainLayout;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPResolverEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPResolverEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPResolverEditorWindow.java
new file mode 100644
index 0000000..530fddb
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPResolverEditorWindow.java
@@ -0,0 +1,226 @@
+/*
+ *  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.view.windows;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.jpa.PIPResolver;
+import org.apache.openaz.xacml.admin.view.fields.ResolverParamField;
+import com.vaadin.addon.jpacontainer.EntityItem;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
+import com.vaadin.data.fieldgroup.PropertyId;
+import com.vaadin.event.FieldEvents.TextChangeEvent;
+import com.vaadin.event.FieldEvents.TextChangeListener;
+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.GridLayout;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.Window;
+
+public class PIPResolverEditorWindow extends Window {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(PIPResolverEditorWindow.class);
+	private final PIPResolverEditorWindow self = this;
+	
+	private final EntityItem<PIPResolver> entity;
+	private FieldGroup fieldGroup;
+	private boolean isSaved = false;
+	private GridLayout grid = new GridLayout(2,4);
+	
+	@PropertyId("name")
+	TextField fieldName = new TextField("Name");
+	
+	@PropertyId("description")
+	TextArea areaDescription = new TextArea("Description");
+
+	@PropertyId("issuer")
+	TextField fieldIssuer = new TextField("Issuer");
+	
+	@PropertyId("pipresolverParams")
+	ResolverParamField paramField;
+	
+	Button	buttonSave = new Button("Save");
+
+	/**
+	 * 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 PIPResolverEditorWindow(EntityItem<PIPResolver> entity) {
+		//
+		// Our base component
+		//
+		this.setContent(this.grid);
+		this.grid.setMargin(true);
+		this.grid.setSpacing(true);
+		//
+		// Save
+		//
+		this.entity = entity;
+		//
+		// Set our shortcuts
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// Initialize
+		//
+		this.initialize();
+		//
+		// Add components
+		//
+		this.grid.addComponent(this.fieldName, 0, 0);
+		this.grid.addComponent(this.fieldIssuer, 0, 1);
+		this.grid.addComponent(this.areaDescription, 0, 2);
+		this.grid.addComponent(this.paramField, 1, 0, 1, 2);
+		this.grid.addComponent(this.buttonSave, 0, 3, 1, 3);
+		//
+		// Bind and initialize
+		//
+		this.initializeFields();
+		//
+		// Post initialize
+		//
+		this.initializeButtons();
+		//
+		// Set focus
+		//
+		this.fieldName.focus();
+		//
+		// Initially call this to see if the entity is already
+		// saveable
+		//
+		this.formChanged();
+	}
+	
+	protected void initialize() {
+		//
+		//
+		//
+		this.fieldName.setImmediate(true);
+		this.fieldName.setNullRepresentation("");
+		this.fieldName.setRequired(true);
+		this.fieldName.setRequiredError("Enter a name for the resolver");
+		this.fieldName.setInputPrompt("Eg. \"Resolve employee type\"");
+
+		this.fieldIssuer.setNullRepresentation("");
+		this.fieldIssuer.setRequired(false);
+		this.fieldIssuer.setInputPrompt("Eg. urn:com:sample:hr");
+		
+		this.areaDescription.setNullRepresentation("");
+		this.areaDescription.setRequired(false);
+		this.areaDescription.setInputPrompt("Optionally write a description for this resolver.");
+		this.areaDescription.setRows(3);
+		this.areaDescription.setWidth("100%");
+		//
+		// Create our field
+		//
+		this.paramField = new ResolverParamField(this.entity);
+		//this.paramField.setValidationVisible(false);
+	}
+	
+	protected void initializeFields() {
+		//
+		// Now create our field group and bind our fields.
+		// This will populate the components with the
+		// current value if we are editing an entity.
+		//
+		this.fieldGroup = new FieldGroup(this.entity);
+		this.fieldGroup.bindMemberFields(this);
+		//
+		//
+		//
+		this.fieldName.addTextChangeListener(new TextChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void textChange(TextChangeEvent event) {
+				self.formChanged();
+			}
+		});
+		//
+		//
+		//
+		this.paramField.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.formChanged();
+			}			
+		});
+	}
+
+	protected void formChanged() {
+		if (this.fieldGroup.isValid() || this.entity.isModified()) {
+			this.buttonSave.setEnabled(true);
+		} else {
+			this.buttonSave.setEnabled(false);
+		}
+	}
+	
+	protected void initializeButtons() {
+		this.grid.setComponentAlignment(this.buttonSave, Alignment.BOTTOM_CENTER);
+		this.buttonSave.setImmediate(true);
+		this.buttonSave.setEnabled(false);
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				try {
+					//
+					// Commit changes
+					//
+					self.fieldGroup.commit();
+					//
+					// Save
+					//
+					self.isSaved = true;
+					//
+					// We can close
+					//
+					self.close();
+				} catch (CommitException e) {
+					logger.warn("Couldn't commit, the save button should NOT be enabled.");
+				}
+			}			
+		});
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPSQLResolverEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPSQLResolverEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPSQLResolverEditorWindow.java
new file mode 100644
index 0000000..2fb4a25
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PIPSQLResolverEditorWindow.java
@@ -0,0 +1,1199 @@
+/*
+ *  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.view.windows;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.jpa.Attribute;
+import org.apache.openaz.xacml.admin.jpa.PIPResolver;
+import org.apache.openaz.xacml.admin.jpa.PIPResolverParam;
+import org.apache.openaz.xacml.admin.util.AdminNotification;
+import org.apache.openaz.xacml.admin.util.XACMLConstants;
+import org.apache.openaz.xacml.admin.view.events.FormChangedEventListener;
+import org.apache.openaz.xacml.admin.view.events.FormChangedEventNotifier;
+import org.apache.openaz.xacml.api.XACML3;
+import org.apache.openaz.xacml.std.pip.engines.csv.ConfigurableCSVResolver;
+import org.apache.openaz.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver;
+import org.apache.openaz.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver;
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.vaadin.addon.jpacontainer.EntityItem;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Buffered.SourceException;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.data.util.BeanItemContainer;
+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.CheckBox;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+
+public class PIPSQLResolverEditorWindow extends CustomComponent implements FormChangedEventNotifier, Handler {
+	
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+
+	@AutoGenerated
+	private Table tableAttributes;
+
+	@AutoGenerated
+	private Table tableRequiredAttributes;
+
+	@AutoGenerated
+	private CheckBox checkBoxShortIds;
+
+	@AutoGenerated
+	private TextField textFieldFilter;
+
+	@AutoGenerated
+	private TextField textFieldBase;
+
+	@AutoGenerated
+	private TextArea textAreaSelect;
+
+	private final Action ADD_ATTRIBUTE = new Action("Add Attribute");
+	private final Action EDIT_ATTRIBUTE = new Action("Edit Attribute");
+	private final Action CLONE_ATTRIBUTE = new Action("Clone Attribute");
+	private final Action REMOVE_ATTRIBUTE = new Action("Remove Attribute");
+	
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	/**
+	 * 
+	 */
+	
+	protected class ResolverAttribute implements Serializable {
+		private static final long serialVersionUID = 1L;
+		String	identifier = null;
+		String	prefix = null;
+		PIPResolverParam	id = null;
+		PIPResolverParam	category = null;
+		PIPResolverParam	datatype = null;
+		PIPResolverParam	issuer = null;
+		PIPResolverParam	column = null;
+		
+		public ResolverAttribute(String prefix, String identifier) {
+			this.prefix = prefix;
+			this.identifier = identifier;
+		}
+		
+		public ResolverAttribute(String prefix, String identifier, ResolverAttribute target) {
+			this(prefix, identifier);
+			this.setId(target.getId());
+			this.setCategory(target.getCategory());
+			this.setDatatype(target.getDatatype());
+			this.setIssuer(target.getIssuer());
+			this.setColumn(target.getColumn());
+			this.setResolver(target.id.getPipresolver());
+		}
+
+		public String	getIdentifier() {
+			return this.identifier;
+		}
+		
+		public String	getId() {
+			if (this.id == null) {
+				return null;
+			}
+			return this.id.getParamValue();
+		}
+		
+		public String	getShortId() {
+			String id = this.getId();
+			if (id == null) {
+				return null;
+			}
+			return XACMLConstants.extractShortName(id);
+		}
+		
+		public PIPResolverParam getIdParam() {
+			return this.id;
+		}
+		
+		public void		setId(String id) {
+			if (this.id == null) {
+				this.id = new PIPResolverParam();
+				this.id.setParamName(this.prefix + this.identifier + ".id");
+			}
+			this.id.setParamValue(id);
+		}
+		
+		public void		setId(PIPResolverParam param) {
+			this.id = param;
+		}
+		
+		public String	getCategory() {
+			if (this.category == null) {
+				return null;
+			}
+			return this.category.getParamValue();
+		}
+		
+		public String	getShortCategory() {
+			String category = this.getCategory();
+			if (category == null) {
+				return null;
+			}
+			return XACMLConstants.extractShortName(category);
+		}
+		
+		public PIPResolverParam	getCategoryParam() {
+			return this.category;
+		}
+		
+		public void		setCategory(String category) {
+			if (this.category == null) {
+				this.category = new PIPResolverParam();
+				this.category.setParamName(this.prefix + this.identifier + ".category");
+			}
+			this.category.setParamValue(category);
+		}
+		
+		public void setCategory(PIPResolverParam param) {
+			this.category = param;
+		}
+		
+		public String	getDatatype() {
+			if (this.datatype == null) {
+				return null;
+			}
+			return this.datatype.getParamValue();
+		}
+		
+		public String	getShortDatatype() {
+			String dt = this.getDatatype();
+			if (dt == null) {
+				return null;
+			}
+			return XACMLConstants.extractShortName(dt);
+		}
+		
+		public PIPResolverParam getDatatypeParam() {
+			return this.datatype;
+		}
+		
+		public void		setDatatype(String datatype) {
+			if (this.datatype == null) {
+				this.datatype = new PIPResolverParam();
+				this.datatype.setParamName(this.prefix + this.identifier + ".datatype");
+			}
+			this.datatype.setParamValue(datatype);
+		}
+		
+		public void		setDatatype(PIPResolverParam param) {
+			this.datatype = param;
+		}
+		
+		public String	getIssuer() {
+			if (this.issuer == null) {
+				return null;
+			}
+			return this.issuer.getParamValue();
+		}
+		
+		public String	getShortIssuer() {
+			String issuer = this.getIssuer();
+			if (issuer == null) {
+				return null;
+			}
+			return XACMLConstants.extractShortName(issuer);
+		}
+		
+		public PIPResolverParam getIssuerParam() {
+			return this.issuer;
+		}
+		
+		public void		setIssuer(String issuer) {
+			if (this.issuer == null) {
+				this.issuer = new PIPResolverParam();
+				this.issuer.setParamName(this.prefix + this.identifier + ".issuer");
+			}
+			this.issuer.setParamValue(issuer);
+		}
+
+		public void		setIssuer(PIPResolverParam param) {
+			this.issuer = param;
+		}
+		
+		public Integer		getColumn() {
+			if (this.column == null) {
+				return null;
+			}
+			try {
+				return Integer.parseInt(this.column.getParamValue());
+			} catch (NumberFormatException e) {
+				logger.error("Failed to set column: " + e);
+				return null;
+			}
+		}
+		
+		public PIPResolverParam getColumnParam() {
+			return this.column;
+		}
+		
+		public void	setColumn(Integer col) {
+			if (this.column == null) {
+				this.column = new PIPResolverParam();
+				this.column.setParamName(this.prefix + this.identifier + "column");
+			}
+			this.column.setParamValue(col.toString());
+		}
+		
+		public void setColumn(PIPResolverParam param) {
+			this.column = param;
+		}
+
+		public void setResolver(PIPResolver resolver) {
+			if (this.id != null) {
+				this.id.setPipresolver(resolver);
+			}
+			if (this.category != null) {
+				this.category.setPipresolver(resolver);
+			}
+			if (this.datatype != null) {
+				this.datatype.setPipresolver(resolver);
+			}
+			if (this.issuer != null) {
+				this.issuer.setPipresolver(resolver);
+			}
+			if (this.column != null) {
+				this.column.setPipresolver(resolver);
+			}
+		}
+	}	
+	
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(PIPSQLResolverEditorWindow.class);
+	private final PIPSQLResolverEditorWindow self = this;
+	private final EntityItem<PIPResolver> entity;
+	private final BeanItemContainer<ResolverAttribute> fieldsContainer = new BeanItemContainer<ResolverAttribute>(ResolverAttribute.class);
+	private final BeanItemContainer<ResolverAttribute> parametersContainer = new BeanItemContainer<ResolverAttribute>(ResolverAttribute.class);
+	private final BasicNotifier notifier = new BasicNotifier();
+	boolean isSaved = false;
+	String fieldPrefix;
+	String parameterPrefix;
+	
+	/**
+	 * 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 PIPSQLResolverEditorWindow(EntityItem<PIPResolver> entity) {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Save
+		//
+		this.entity = entity;
+		//
+		// Initialize
+		//
+		this.initialize();
+	}
+	
+	protected boolean isSQL() {
+		if (this.entity.getEntity().getPipconfiguration().getPiptype().isSQL() ||
+			this.entity.getEntity().getPipconfiguration().getPiptype().isHyperCSV()) {
+			return true;
+		}
+		return false;
+	}
+	
+	protected boolean isLDAP() {
+		return this.entity.getEntity().getPipconfiguration().getPiptype().isLDAP();
+	}
+	
+	protected boolean isCSV() {
+		return this.entity.getEntity().getPipconfiguration().getPiptype().isCSV();
+	}
+	
+	protected void initialize() {
+		//
+		// Initialize entity
+		//
+		this.initializeEntity();
+		//
+		// Go through the parameters, save them into a
+		// properties object.
+		//
+		boolean sourceInitialized = false;
+		boolean attributeInitialized = false;
+		for (PIPResolverParam param : this.entity.getEntity().getPipresolverParams()) {
+			//
+			// Look for ones we know about
+			//
+			if (param.getParamName().equalsIgnoreCase("select")) {
+				this.textAreaSelect.setValue(param.getParamValue());
+				this.textAreaSelect.setData(param);
+			} else if (param.getParamName().equals("fields") || param.getParamName().equals("filter.view")) {
+				this.initializeSourceTable(param.getParamValue());
+				this.tableRequiredAttributes.setData(param);
+				sourceInitialized = true;
+			} else if (param.getParamName().equals("parameters") || param.getParamName().equals("filter.parameters")) {
+				this.initializeAttributeTable(param.getParamValue());
+				this.tableAttributes.setData(param);
+				attributeInitialized = true;
+			} else if (param.getParamName().equalsIgnoreCase("base")) {
+				this.textFieldBase.setValue(param.getParamValue());
+				this.textFieldBase.setData(param);
+			} else if (param.getParamName().equalsIgnoreCase("filter")) {
+				this.textFieldFilter.setValue(param.getParamValue());
+				this.textFieldFilter.setData(param);
+			}
+		}
+		//
+		// Initialize GUI
+		//
+		this.initializeText();
+		this.initializeCheckBox();
+		//
+		// Verify the tables get setup, if this is a new object
+		// then they haven't been.
+		//
+		if (sourceInitialized == false) {
+			this.initializeSourceTable("");
+		}
+		if (attributeInitialized == false) {
+			this.initializeAttributeTable("");
+		}
+	}
+	
+	protected void initializeEntity() {
+		//
+		// Make sure the classname is set correctly
+		//
+		if (this.isSQL()) {
+			//
+			//
+			//
+			this.fieldPrefix = "field.";
+			this.parameterPrefix = "parameter.";
+			this.entity.getEntity().setClassname(ConfigurableJDBCResolver.class.getCanonicalName());
+		} else if (this.isLDAP()) {
+			//
+			//
+			//
+			this.fieldPrefix = "filter.view.";
+			this.parameterPrefix = "filter.parameters.";
+			this.entity.getEntity().setClassname(ConfigurableLDAPResolver.class.getCanonicalName());
+		} else if (this.isCSV()) {
+			//
+			//
+			//
+			this.fieldPrefix = "field.";
+			this.parameterPrefix = "parameter.";
+			this.entity.getEntity().setClassname(ConfigurableCSVResolver.class.getCanonicalName());
+		}
+	}
+	
+	protected void initializeText() {
+		//
+		// Are we SQL or LDAP?
+		//
+		if (this.isSQL()) {
+			//
+			// Turn these off
+			//
+			this.textFieldBase.setRequired(false);
+			this.textFieldBase.setVisible(false);
+			this.textFieldFilter.setRequired(false);
+			this.textFieldFilter.setVisible(false);
+			//
+			// GUI properties
+			//
+			this.textAreaSelect.setImmediate(true);
+			//
+			// Respond to changes
+			//
+			this.textAreaSelect.addValueChangeListener(new ValueChangeListener() {
+				private static final long serialVersionUID = 1L;
+	
+				@Override
+				public void valueChange(ValueChangeEvent event) {
+					PIPResolverParam param = (PIPResolverParam) self.textAreaSelect.getData();
+					if (param == null) {
+						param = new PIPResolverParam();
+						param.setPipresolver(self.entity.getEntity());
+						param.setParamName("select");
+						self.entity.getEntity().addPipresolverParam(param);
+						self.textAreaSelect.setData(param);
+					}
+					param.setParamValue(self.textAreaSelect.getValue());
+					self.fireFormChangedEvent();
+				}			
+			});
+		} else if (this.isLDAP()) {
+			//
+			// Turn these off
+			//
+			this.textAreaSelect.setRequired(false);
+			this.textAreaSelect.setVisible(false);
+			//
+			//
+			//
+			this.textFieldBase.setImmediate(true);
+			this.textFieldBase.addValueChangeListener(new ValueChangeListener() {
+				private static final long serialVersionUID = 1L;
+				
+				@Override
+				public void valueChange(ValueChangeEvent event) {
+					PIPResolverParam param = (PIPResolverParam) self.textFieldBase.getData();
+					if (param == null) {
+						param = new PIPResolverParam();
+						param.setPipresolver(self.entity.getEntity());
+						param.setParamName("base");
+						self.entity.getEntity().addPipresolverParam(param);
+						self.textFieldBase.setData(param);
+					}
+					param.setParamValue(self.textFieldBase.getValue());
+					self.fireFormChangedEvent();
+				}			
+			});
+			//
+			//
+			//
+			this.textFieldFilter.setImmediate(true);
+			this.textFieldFilter.addValueChangeListener(new ValueChangeListener() {
+				private static final long serialVersionUID = 1L;
+				
+				@Override
+				public void valueChange(ValueChangeEvent event) {
+					PIPResolverParam param = (PIPResolverParam) self.textFieldFilter.getData();
+					if (param == null) {
+						param = new PIPResolverParam();
+						param.setPipresolver(self.entity.getEntity());
+						param.setParamName("filter");
+						self.entity.getEntity().addPipresolverParam(param);
+						self.textFieldFilter.setData(param);
+					}
+					param.setParamValue(self.textFieldFilter.getValue());
+					self.fireFormChangedEvent();
+				}			
+			});
+		} else if (this.isCSV()) {
+			//
+			// Turn these off
+			//
+			this.textAreaSelect.setRequired(false);
+			this.textAreaSelect.setVisible(false);
+			this.textFieldBase.setRequired(false);
+			this.textFieldBase.setVisible(false);
+			this.textFieldFilter.setRequired(false);
+			this.textFieldFilter.setVisible(false);
+		}
+	}
+	
+	protected void initializeCheckBox() {
+		this.checkBoxShortIds.setValue(true);
+		this.checkBoxShortIds.setImmediate(true);
+		this.checkBoxShortIds.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				if (self.checkBoxShortIds.getValue()) {
+					self.tableRequiredAttributes.setColumnCollapsed("id", true);
+					self.tableRequiredAttributes.setColumnCollapsed("category", true);
+					self.tableRequiredAttributes.setColumnCollapsed("datatype", true);
+					self.tableRequiredAttributes.setColumnCollapsed("shortId", false);
+					self.tableRequiredAttributes.setColumnCollapsed("shortCategory", false);
+					self.tableRequiredAttributes.setColumnCollapsed("shortDatatype", false);
+				} else {
+					self.tableRequiredAttributes.setColumnCollapsed("id", false);
+					self.tableRequiredAttributes.setColumnCollapsed("category", false);
+					self.tableRequiredAttributes.setColumnCollapsed("datatype", false);
+					self.tableRequiredAttributes.setColumnCollapsed("shortId", true);
+					self.tableRequiredAttributes.setColumnCollapsed("shortCategory", true);
+					self.tableRequiredAttributes.setColumnCollapsed("shortDatatype", true);
+				}
+			}			
+		});
+	}
+	
+	protected void initializeSourceTable(String fields) {
+		//
+		// Add data into the container
+		//
+		this.populateData(this.fieldPrefix, fields, this.fieldsContainer);
+		//
+		// Set GUI properties
+		//
+		this.tableRequiredAttributes.setContainerDataSource(this.fieldsContainer);
+		this.tableRequiredAttributes.setPageLength((this.fieldsContainer.size() == 0 ? 3 : this.fieldsContainer.size() + 1));
+		this.tableRequiredAttributes.setSizeFull();
+		this.tableRequiredAttributes.setColumnCollapsingAllowed(true);
+		this.tableRequiredAttributes.setVisibleColumns(new Object[] {"identifier", "id", "category", "datatype", "shortId", "shortCategory", "shortDatatype"});
+		this.tableRequiredAttributes.setColumnHeaders(new String[] {"Field", "Attribute Id", "Category", "Data Type", "Attribute Id", "Category", "Data Type"});
+		this.tableRequiredAttributes.setColumnCollapsed("id", true);
+		this.tableRequiredAttributes.setColumnCollapsed("category", true);
+		this.tableRequiredAttributes.setColumnCollapsed("datatype", true);
+		this.tableRequiredAttributes.setSelectable(true);
+		//
+		// Setup its handler
+		//
+		this.tableRequiredAttributes.addActionHandler(this);
+		//
+		// Respond to events
+		//
+		this.tableRequiredAttributes.addItemClickListener(new ItemClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void itemClick(ItemClickEvent event) {
+				if (event.isDoubleClick()) {
+					Object id = event.getItemId();
+					if (id == null) {
+						//
+						// Really shouldn't get here
+						//
+						return;
+					}
+					BeanItem<ResolverAttribute> beanItem = self.fieldsContainer.getItem(id);
+					if (beanItem == null) {
+						//
+						// Again, shouldn't get here
+						//
+						return;
+					}
+					self.editAttribute(self.tableRequiredAttributes, beanItem.getBean());
+				}
+			}
+		});
+	}
+	
+	protected void initializeAttributeTable(String parameters) {
+		//
+		// Add data into the container
+		//
+		this.populateData(this.parameterPrefix, parameters, this.parametersContainer);
+		//
+		// setup gui properties
+		//
+		this.tableAttributes.setContainerDataSource(this.parametersContainer);
+		this.tableAttributes.setPageLength(this.parametersContainer.size() + 1);
+		this.tableAttributes.setSizeFull();
+		this.tableAttributes.setColumnCollapsingAllowed(true);
+		this.tableAttributes.setVisibleColumns(new Object[] {"identifier", "id", "category", "datatype", "shortId", "shortCategory", "shortDatatype"});
+		this.tableAttributes.setColumnHeaders(new String[] {"Position", "Attribute Id", "Category", "Data Type", "Attribute Id", "Category", "Data Type"});
+		this.tableAttributes.setColumnCollapsed("id", true);
+		this.tableAttributes.setColumnCollapsed("category", true);
+		this.tableAttributes.setColumnCollapsed("datatype", true);
+		this.tableAttributes.setSelectable(true);
+		//
+		// Setup its handler
+		//
+		this.tableAttributes.addActionHandler(this);
+		//
+		// Respond to events
+		//
+		this.tableAttributes.addItemClickListener(new ItemClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void itemClick(ItemClickEvent event) {
+				if (event.isDoubleClick()) {
+					Object id = event.getItemId();
+					if (id == null) {
+						//
+						// Really shouldn't get here
+						//
+						return;
+					}
+					BeanItem<ResolverAttribute> beanItem = self.parametersContainer.getItem(id);
+					if (beanItem == null) {
+						//
+						// Again, shouldn't get here
+						//
+						return;
+					}
+					self.editAttribute(self.tableAttributes, beanItem.getBean());
+				}
+			}
+		});
+	}
+	
+	protected void populateData(String prefix, String list, BeanItemContainer<ResolverAttribute> container) {
+		for (String field : Splitter.on(',').trimResults().omitEmptyStrings().split(list)) {
+			//
+			// Create a bean for this field
+			//
+			ResolverAttribute bean = new ResolverAttribute(prefix, field);
+			//
+			// Now try to find the attribute information
+			//
+			for (PIPResolverParam param : this.entity.getEntity().getPipresolverParams()) {
+				if (param.getParamName().equals(prefix + field + ".id")) {
+					bean.setId(param);
+				} else if (param.getParamName().equals(prefix + field + ".category")) {
+					bean.setCategory(param);
+				} else if (param.getParamName().equals(prefix + field + ".datatype")) {
+					bean.setDatatype(param);
+				} else if (param.getParamName().equals(prefix + field + ".issuer")) {
+					bean.setIssuer(param);
+				} else if (param.getParamName().equals(prefix + field + ".column")) {
+					bean.setColumn(param);
+				}
+			}
+			container.addBean(bean);
+		}
+	}
+
+	@Override
+	public Action[] getActions(Object target, Object sender) {
+		if (target == null) {
+			return new Action[] {ADD_ATTRIBUTE};
+		}
+		return new Action[] {EDIT_ATTRIBUTE, CLONE_ATTRIBUTE, REMOVE_ATTRIBUTE};
+	}
+
+	@Override
+	public void handleAction(Action action, Object sender, Object target) {
+		if (action == ADD_ATTRIBUTE) {
+			if (sender.equals(this.tableRequiredAttributes)) {
+				this.editAttribute(self.tableRequiredAttributes, null);
+			} else {
+				this.editAttribute(self.tableAttributes, null);
+			}
+			return;
+		}
+		if (action == EDIT_ATTRIBUTE) {
+			assert target instanceof ResolverAttribute;
+			if (sender.equals(this.tableRequiredAttributes)) {
+				this.editAttribute(self.tableRequiredAttributes, (ResolverAttribute) target);
+			} else {
+				this.editAttribute(self.tableAttributes, (ResolverAttribute) target);
+			}
+			return;
+		}
+		if (action == CLONE_ATTRIBUTE) {
+			assert target instanceof ResolverAttribute;
+			try {
+				//
+				// Which table?
+				//
+				if (sender.equals(this.tableRequiredAttributes)) {
+					//
+					// Clone the attribute giving it a new
+					// field name.
+					//
+					ResolverAttribute clone = new ResolverAttribute(this.fieldPrefix, this.getNextField(), (ResolverAttribute) target);
+					//
+					// Add it to the container
+					//
+					this.fieldsContainer.addBean(clone);
+					//
+					// Reset the page length so we can see it and have room
+					// to add another.
+					//
+					this.tableRequiredAttributes.setPageLength(this.fieldsContainer.size() + 1);
+					//
+					// Select it
+					//
+					this.tableRequiredAttributes.select(clone);
+				} else {
+					//
+					// Clone the attribute giving it a new
+					// field name.
+					//
+					ResolverAttribute clone = new ResolverAttribute(this.parameterPrefix, this.getNextParameter(), (ResolverAttribute) target);
+					//
+					// Add it to the container
+					//
+					this.parametersContainer.addBean(clone);
+					//
+					// Reset the page length so we can see it and have room
+					// to add another.
+					//
+					this.tableAttributes.setPageLength(this.parametersContainer.size() + 1);
+					//
+					// Select it
+					//
+					this.tableAttributes.select(clone);
+				}
+				//
+				// We have changed
+				//
+				this.fireFormChangedEvent();
+			} catch (Exception e) {
+				logger.error("Failed to clone: " + e);
+			}
+			return;
+		}
+		if (action == REMOVE_ATTRIBUTE) {
+			assert target instanceof ResolverAttribute;
+			//
+			// Help method to remove the attribute
+			//
+			this.removeAttribute((ResolverAttribute) target);
+			//
+			// Which table?
+			//
+			if (sender.equals(this.tableRequiredAttributes)) {
+				//
+				// Now remove it from the table
+				//
+				this.tableRequiredAttributes.removeItem(target);
+			} else {
+				//
+				// Now remove it from the table
+				//
+				this.tableAttributes.removeItem(target);
+			}
+			//
+			// we have changed
+			//
+			this.fireFormChangedEvent();
+			return;
+		}
+	}
+
+	protected void removeAttribute(ResolverAttribute target) {
+		this.entity.getEntity().removePipresolverParam(target.getIdParam());
+		this.entity.getEntity().removePipresolverParam(target.getCategoryParam());
+		this.entity.getEntity().removePipresolverParam(target.getDatatypeParam());
+		this.entity.getEntity().removePipresolverParam(target.getIssuerParam());
+	}
+
+	protected void editAttribute(final Table table, final ResolverAttribute request) {
+		if (this.isCSV()) {
+			this.editCSVAttribute(table, request);
+		} else {
+			this.editResolverAttribute(table, request, null);
+		}
+	}
+	
+	protected void editCSVAttribute(final Table table, final ResolverAttribute request) {
+		assert this.isCSV();
+		//
+		// Prompt for the column
+		//
+		final ColumnSelectionWindow window = new ColumnSelectionWindow((request != null ? request.getColumn() : 0));
+		if (request == null) {
+			window.setCaption("Input the CSV Column for the new attribute");
+		} else {
+			window.setCaption("Edit the CSV Column for the attribute");
+		}
+		window.setModal(true);
+		window.center();
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user save?
+				//
+				if (window.isSaved() == false) {
+					return;
+				}
+				//
+				// Save it if its not a new
+				//
+				if (request != null) {
+					request.setColumn(window.getColumn());
+				}
+				//
+				// Now we select the attribute, pass the column
+				// in case this is a brand new attribute. Yeah its messy.
+				//
+				self.editResolverAttribute(table, request, window.getColumn());
+			}
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+
+	protected void editResolverAttribute(final Table table, final ResolverAttribute request, final Integer column) {
+		//
+		// Provide objects to the attribute selection window
+		//
+		AttributeDesignatorType designator = new AttributeDesignatorType();
+		if (request == null) {
+			designator.setAttributeId(XACML3.ID_SUBJECT_SUBJECT_ID.stringValue());
+			designator.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
+			designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
+			designator.setIssuer(this.entity.getEntity().getIssuer());
+		} else {
+			designator.setAttributeId(request.getId());
+			designator.setCategory(request.getCategory());
+			designator.setDataType(request.getDatatype());
+			designator.setIssuer(request.getIssuer());
+		}
+		//
+		// Have user select an attribute
+		//
+		final AttributeSelectionWindow selection = new AttributeSelectionWindow(null, designator);
+		selection.setModal(true);
+		selection.setCaption("Select Attribute");
+		selection.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent event) {
+				//
+				// User click Save button?
+				//
+				if (selection.isSaved() == false) {
+					return;
+				}
+				//
+				// Yes - get the final attribute
+				//
+				Attribute attribute = selection.getAttribute();
+				//
+				// Is it a new one?
+				//
+				if (request == null) {
+					try {
+						//
+						// Create a new bean
+						//
+						ResolverAttribute bean = null;
+						if (table.equals(self.tableRequiredAttributes)) {
+							bean = new ResolverAttribute(self.fieldPrefix, self.getNextField());
+						} else {
+							bean = new ResolverAttribute(self.parameterPrefix, self.getNextParameter());
+						}
+						bean.setId(attribute.getXacmlId());
+						bean.setCategory(attribute.getCategoryBean().getXacmlId());
+						bean.setDatatype(attribute.getDatatypeBean().getXacmlId());
+						if (attribute.getIssuer() != null) {
+							bean.setIssuer(attribute.getIssuer());
+						}
+						if (column != null) {
+							bean.setColumn(column);
+						}
+						//
+						// Add it to the resolver
+						//
+						bean.setResolver(self.entity.getEntity());
+						self.entity.getEntity().addPipresolverParam(bean.getIdParam());
+						self.entity.getEntity().addPipresolverParam(bean.getCategoryParam());
+						self.entity.getEntity().addPipresolverParam(bean.getDatatypeParam());
+						if (bean.getIssuer() != null) {
+							self.entity.getEntity().addPipresolverParam(bean.getIssuerParam());
+						}
+						//
+						// Which table?
+						//
+						if (table.equals(self.tableRequiredAttributes)) {
+							//
+							// Add to table
+							//
+							self.fieldsContainer.addBean(bean);
+							//
+							// Reset the page length
+							//
+							self.tableRequiredAttributes.setPageLength(self.fieldsContainer.size() + 1);
+						} else if (table.equals(self.tableAttributes)) {
+							//
+							// Add to table
+							//
+							self.parametersContainer.addBean(bean);
+							//
+							// Reset the page length
+							//
+							self.tableAttributes.setPageLength(self.parametersContainer.size() + 1);
+						}
+						if (logger.isDebugEnabled()) {
+							logger.debug("Added new attribute: " + bean);
+						}
+					} catch (Exception e) {
+						logger.error(e);
+						AdminNotification.error("Unable to add another required attribute field");
+					}
+				} else {
+					//
+					// Update the table entry
+					//
+					request.setId(attribute.getXacmlId());
+					request.setCategory(attribute.getCategoryBean().getXacmlId());
+					request.setDatatype(attribute.getDatatypeBean().getXacmlId());
+					request.setIssuer(attribute.getIssuer());
+					//
+					// Let the table know
+					//
+					table.refreshRowCache();
+				}
+				//
+				// we have changed
+				//
+				self.fireFormChangedEvent();
+			}
+		});
+		selection.center();
+		UI.getCurrent().addWindow(selection);
+	}
+	
+	protected String	getNextField() throws Exception {
+		//
+		// Start at the next index number. NOTE: The GUI needs
+		// to use numbers to index the fields.
+		//
+		int index = this.tableRequiredAttributes.size() + 1;
+		//
+		// Really if we get to 100, that's an insane number of fields
+		// needed for a SQL query.
+		//
+		while (index < 100) {
+			String field = String.format("%02d", index);
+			boolean exists = false;
+			for (Object id : this.tableRequiredAttributes.getItemIds()) {
+				@SuppressWarnings("unchecked")
+				BeanItem<ResolverAttribute> required = (BeanItem<ResolverAttribute>) this.tableRequiredAttributes.getItem(id);
+				if (required.getBean().getIdentifier().equals(field)) {
+					exists = true;
+					index++;
+					break;
+				}
+			}
+			if (exists == false) {
+				return field;
+			}
+		}
+		//
+		// Sanity check
+		//
+		throw new Exception("Unable to find a next field name. Are there too many fields?");
+	}
+	
+	protected String	getNextParameter() throws Exception {
+		//
+		// Start at the next index number. NOTE: The GUI needs
+		// to use numbers to index the fields.
+		//
+		int index = this.tableAttributes.size() + 1;
+		//
+		// Really if we get to 100, that's an insane number of fields
+		// needed for a SQL query.
+		//
+		while (index < 100) {
+			String field = String.format("%02d", index);
+			boolean exists = false;
+			for (Object id : this.tableAttributes.getItemIds()) {
+				@SuppressWarnings("unchecked")
+				BeanItem<ResolverAttribute> required = (BeanItem<ResolverAttribute>) this.tableAttributes.getItem(id);
+				if (required.getBean().getIdentifier().equals(field)) {
+					exists = true;
+					index++;
+					break;
+				}
+			}
+			if (exists == false) {
+				return field;
+			}
+		}
+		//
+		// Sanity check
+		//
+		throw new Exception("Unable to find a next parameter name. Are there too many parameters?");
+	}
+	
+	public void discard() throws SourceException {
+		if (this.isSQL()) {
+			this.textAreaSelect.discard();
+		} else if (this.isLDAP()) {
+			this.textFieldBase.discard();
+			this.textFieldFilter.discard();
+		// } else if (this.isCSV()) {
+		}
+	}
+	
+	public void validate() throws InvalidValueException {
+		if (this.isSQL()) {
+			this.textAreaSelect.validate();
+		} else if (this.isLDAP()) {
+			this.textFieldBase.validate();
+			this.textFieldFilter.validate();
+		//} else if (this.isCSV()) {
+			
+		}
+	}
+	
+	public void commit() throws SourceException, InvalidValueException {
+		//
+		// Commit required fields
+		//
+		if (this.isSQL()) {
+			this.textAreaSelect.commit();
+		} else if (this.isLDAP()) {
+			this.textFieldBase.commit();
+			this.textFieldFilter.commit();
+		// } else if (this.isCSV()) {
+		}
+		//
+		// Setup the fields
+		//
+		{
+			List<String> fields = new ArrayList<String>(this.fieldsContainer.size());
+			for (ResolverAttribute attribute : this.fieldsContainer.getItemIds()) {
+				fields.add(attribute.getIdentifier());
+			}
+			PIPResolverParam param = (PIPResolverParam) this.tableRequiredAttributes.getData();
+			if (param == null) {
+				param = new PIPResolverParam();
+				if (this.isSQL()) {
+					param.setParamName("fields");
+				} else if (this.isLDAP()) {
+					param.setParamName("filter.view");
+				} else if (this.isCSV()) {
+					param.setParamName("fields");
+				}
+				this.entity.getEntity().addPipresolverParam(param);
+				this.tableRequiredAttributes.setData(param);
+			}
+			param.setParamValue(Joiner.on(',').join(fields));
+		}
+		//
+		// Setup the parameters
+		//
+		{
+			List<String> parameters = new ArrayList<String>(this.parametersContainer.size());
+			for (ResolverAttribute attribute : this.parametersContainer.getItemIds()) {
+				parameters.add(attribute.getIdentifier());
+			}
+			PIPResolverParam param = (PIPResolverParam) this.tableAttributes.getData();
+			if (param == null) {
+				param = new PIPResolverParam();
+				if (this.isSQL()) {
+					param.setParamName("parameters");
+				} else if (this.isLDAP()) {
+					param.setParamName("filter.parameters");
+				} else if (this.isCSV()) {
+					param.setParamName("parameters");
+				}
+				this.entity.getEntity().addPipresolverParam(param);
+				this.tableAttributes.setData(param);
+			}
+			param.setParamValue(Joiner.on(',').join(parameters));
+		}
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	@Override
+	public boolean addListener(FormChangedEventListener listener) {
+		return this.notifier.addListener(listener);
+	}
+
+	@Override
+	public boolean removeListener(FormChangedEventListener listener) {
+		return this.notifier.removeListener(listener);
+	}
+
+	@Override
+	public void fireFormChangedEvent() {
+		this.notifier.fireFormChangedEvent();
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("-1px");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(true);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("-1px");
+		setHeight("-1px");
+		
+		// textAreaSelect
+		textAreaSelect = new TextArea();
+		textAreaSelect.setCaption("SQL Select Statement");
+		textAreaSelect.setImmediate(false);
+		textAreaSelect.setWidth("100.0%");
+		textAreaSelect.setHeight("-1px");
+		textAreaSelect.setInvalidAllowed(false);
+		textAreaSelect.setRequired(true);
+		mainLayout.addComponent(textAreaSelect);
+		mainLayout.setExpandRatio(textAreaSelect, 1.0f);
+		
+		// textFieldBase
+		textFieldBase = new TextField();
+		textFieldBase.setCaption("Base DN");
+		textFieldBase.setImmediate(false);
+		textFieldBase.setWidth("-1px");
+		textFieldBase.setHeight("-1px");
+		mainLayout.addComponent(textFieldBase);
+		
+		// textFieldFilter
+		textFieldFilter = new TextField();
+		textFieldFilter.setCaption("Filter");
+		textFieldFilter.setImmediate(false);
+		textFieldFilter.setWidth("-1px");
+		textFieldFilter.setHeight("-1px");
+		mainLayout.addComponent(textFieldFilter);
+		
+		// checkBoxShortIds
+		checkBoxShortIds = new CheckBox();
+		checkBoxShortIds.setCaption("Display short id’s.");
+		checkBoxShortIds.setImmediate(false);
+		checkBoxShortIds.setWidth("-1px");
+		checkBoxShortIds.setHeight("-1px");
+		mainLayout.addComponent(checkBoxShortIds);
+		
+		// tableRequiredAttributes
+		tableRequiredAttributes = new Table();
+		tableRequiredAttributes.setCaption("Attributes Returned");
+		tableRequiredAttributes.setImmediate(false);
+		tableRequiredAttributes.setWidth("-1px");
+		tableRequiredAttributes.setHeight("-1px");
+		mainLayout.addComponent(tableRequiredAttributes);
+		
+		// tableAttributes
+		tableAttributes = new Table();
+		tableAttributes.setCaption("Parameters - Attributes Needed (i.e. ?)");
+		tableAttributes.setImmediate(false);
+		tableAttributes.setWidth("-1px");
+		tableAttributes.setHeight("-1px");
+		tableAttributes.setInvalidAllowed(false);
+		tableAttributes.setRequired(true);
+		mainLayout.addComponent(tableAttributes);
+		
+		return mainLayout;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicyEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicyEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicyEditorWindow.java
new file mode 100644
index 0000000..f9d70c8
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicyEditorWindow.java
@@ -0,0 +1,252 @@
+/*
+ *  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.view.windows;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.jpa.RuleAlgorithms;
+import org.apache.openaz.xacml.admin.util.JPAUtils;
+import org.apache.openaz.xacml.api.XACML3;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Buffered.SourceException;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.validator.RegexpValidator;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
+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.Label;
+import com.vaadin.ui.ListSelect;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class PolicyEditorWindow extends Window {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Button buttonSave;
+	@AutoGenerated
+	private TextArea textAreaDescription;
+	@AutoGenerated
+	private ListSelect listSelectAlgorithm;
+	@AutoGenerated
+	private TextField textFieldVersion;
+	@AutoGenerated
+	private Label labelID;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private final PolicyEditorWindow self = this;
+	private final PolicyType policy;
+	private JPAContainer<RuleAlgorithms> algorithms = ((XacmlAdminUI)UI.getCurrent()).getRuleAlgorithms();
+	private boolean isSaved = false;
+	/**
+	 * 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 PolicyEditorWindow(PolicyType policy) {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Save
+		//
+		this.policy = policy;
+		//
+		// Close shortcut
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// Initialize GUI
+		//
+		this.initializeLabel();
+		this.initializeText();
+		this.initializeSelect();
+		this.initializeButton();
+		//
+		// Focus
+		//
+		this.textAreaDescription.focus();
+	}
+	
+	protected void initializeLabel() {
+		if (this.policy.getPolicyId() == null) {
+			this.policy.setPolicyId(((XacmlAdminUI)UI.getCurrent()).newPolicyID());
+		}
+		this.labelID.setValue(this.policy.getPolicyId());
+	}
+	
+	protected void initializeText() {
+		//
+		//
+		//
+		this.textAreaDescription.setNullRepresentation("");
+		this.textAreaDescription.setValue(this.policy.getDescription());
+		//
+		//
+		//
+		if (this.policy.getVersion() == null) {
+			this.policy.setVersion("1");
+		}
+		this.textFieldVersion.setRequiredError("The exact format is: ((\\d+|\\*)\\.)*(\\d+|\\*|\\+)");
+		this.textFieldVersion.addValidator(new RegexpValidator("((\\d+|\\*)\\.)*(\\d+|\\*|\\+)", true, "The version MUST a number optionally separated by '.' eg. 1 or 1.0 or 1.1.1 etc."));
+		this.textFieldVersion.setValue(this.policy.getVersion());
+	}
+	
+	protected void initializeSelect() {
+		this.listSelectAlgorithm.setContainerDataSource(this.algorithms);
+		this.listSelectAlgorithm.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+		this.listSelectAlgorithm.setItemCaptionPropertyId("xacmlId");
+		this.listSelectAlgorithm.setNullSelectionAllowed(false);
+		
+		if (this.policy.getRuleCombiningAlgId() == null) {
+			this.policy.setRuleCombiningAlgId(XACML3.ID_RULE_FIRST_APPLICABLE.stringValue());
+		}
+		this.listSelectAlgorithm.setValue(JPAUtils.findRuleAlgorithm(this.policy.getRuleCombiningAlgId()).getId());
+	}
+	
+	protected void initializeButton() {
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				try {
+					//
+					// Commit
+					//
+					self.listSelectAlgorithm.commit();
+					self.textFieldVersion.commit();
+					self.textAreaDescription.commit();
+					//
+					// Save everything
+					//
+					self.policy.setDescription(self.textAreaDescription.getValue());
+					self.policy.setVersion(self.textFieldVersion.getValue());
+					Object id = self.listSelectAlgorithm.getValue();
+					self.policy.setRuleCombiningAlgId(algorithms.getItem(id).getEntity().getXacmlId());
+					//
+					// Mark ourselves as saved
+					//
+					self.isSaved = true;
+					//
+					// Close window
+					//
+					self.close();
+				} catch (SourceException | InvalidValueException e) { //NOPMD
+					//
+					// VAADIN will show the required error message to the user
+					//
+				}
+			}
+		});
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public PolicyType getPolicySet() {
+		return this.policy;
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("-1px");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(true);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("-1px");
+		setHeight("-1px");
+		
+		// labelID
+		labelID = new Label();
+		labelID.setCaption("Policy Set ID");
+		labelID.setImmediate(false);
+		labelID.setWidth("100.0%");
+		labelID.setHeight("-1px");
+		labelID.setValue("Label");
+		mainLayout.addComponent(labelID);
+		
+		// textFieldVersion
+		textFieldVersion = new TextField();
+		textFieldVersion.setCaption("Version");
+		textFieldVersion.setImmediate(false);
+		textFieldVersion
+				.setDescription("The format is numbers only separated by decimal point.");
+		textFieldVersion.setWidth("-1px");
+		textFieldVersion.setHeight("-1px");
+		textFieldVersion.setInvalidAllowed(false);
+		textFieldVersion.setRequired(true);
+		textFieldVersion.setInputPrompt("Eg. 1 or 1.0 or 1.0.0 etc.");
+		mainLayout.addComponent(textFieldVersion);
+		
+		// listSelectAlgorithm
+		listSelectAlgorithm = new ListSelect();
+		listSelectAlgorithm.setCaption("Policy Combining Algorithm");
+		listSelectAlgorithm.setImmediate(false);
+		listSelectAlgorithm.setWidth("100.0%");
+		listSelectAlgorithm.setHeight("-1px");
+		listSelectAlgorithm.setInvalidAllowed(false);
+		listSelectAlgorithm.setRequired(true);
+		mainLayout.addComponent(listSelectAlgorithm);
+		
+		// textAreaDescription
+		textAreaDescription = new TextArea();
+		textAreaDescription.setCaption("Description");
+		textAreaDescription.setImmediate(false);
+		textAreaDescription.setWidth("100.0%");
+		textAreaDescription.setHeight("-1px");
+		mainLayout.addComponent(textAreaDescription);
+		mainLayout.setExpandRatio(textAreaDescription, 1.0f);
+		
+		// buttonSave
+		buttonSave = new Button();
+		buttonSave.setCaption("Save");
+		buttonSave.setImmediate(true);
+		buttonSave.setWidth("-1px");
+		buttonSave.setHeight("-1px");
+		mainLayout.addComponent(buttonSave);
+		mainLayout.setComponentAlignment(buttonSave, new Alignment(48));
+		
+		return mainLayout;
+	}
+
+}