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

}
