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:15:31 UTC

[09/23] incubator-openaz git commit: Ported original att source to openaz This Closes #3

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/648d0c0d/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/LDAPPIPConfigurationComponent.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/LDAPPIPConfigurationComponent.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/LDAPPIPConfigurationComponent.java
new file mode 100644
index 0000000..608b0ac
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/LDAPPIPConfigurationComponent.java
@@ -0,0 +1,644 @@
+/*
+ *  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.components;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.jpa.PIPConfigParam;
+import org.apache.openaz.xacml.admin.jpa.PIPConfiguration;
+import org.apache.openaz.xacml.admin.view.events.FormChangedEventListener;
+import org.apache.openaz.xacml.admin.view.events.FormChangedEventNotifier;
+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.event.FieldEvents.TextChangeEvent;
+import com.vaadin.event.FieldEvents.TextChangeListener;
+import com.vaadin.server.Page;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.Notification.Type;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+
+public class LDAPPIPConfigurationComponent extends CustomComponent implements FormChangedEventNotifier {
+	
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+
+	@AutoGenerated
+	private Button buttonTest;
+
+	@AutoGenerated
+	private TextField textFieldScope;
+
+	@AutoGenerated
+	private TextField textFieldCredentials;
+
+	@AutoGenerated
+	private TextField textFieldPrincipal;
+
+	@AutoGenerated
+	private ComboBox comboBoxAuthentication;
+
+	@AutoGenerated
+	private TextField textFieldProviderURL;
+
+	@AutoGenerated
+	private TextField textFieldFactory;
+
+	public static String CLASSNAME = "org.apache.openaz.xacml.std.pip.engines.ldap.LDAPEngine";
+	
+	public static String LDAP_CONTEXT = Context.INITIAL_CONTEXT_FACTORY;
+	public static String LDAP_URL = Context.PROVIDER_URL;
+	public static String LDAP_AUTH = "authentication";
+	public static String LDAP_PRINCIPAL = "principal";
+	public static String LDAP_CREDENTIALS = "credentials";
+	public static String LDAP_SCOPE = "scope";
+	
+	public static String LDAP_DEFAULT_CONTEXT = "com.sun.jndi.ldap.LdapCtxFactory";
+	
+	public static String LDAP_AUTH_ANONYMOUS = "anonymous";
+	public static String LDAP_AUTH_SIMPLE = "simple";
+	public static String LDAP_AUTH_SASL = "SASL";	//????
+
+	/*- 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(LDAPPIPConfigurationComponent.class);
+	private final LDAPPIPConfigurationComponent self = this;
+	private final BasicNotifier notifier = new BasicNotifier();
+	private final EntityItem<PIPConfiguration> entity;
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 * @param configParamField 
+	 */
+	public LDAPPIPConfigurationComponent(EntityItem<PIPConfiguration> entity) {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Save
+		//
+		this.entity = entity;
+		//
+		// Initialize
+		//
+		this.initialize();
+	}
+	
+	protected void initialize() {
+		if (logger.isDebugEnabled()) {
+			logger.debug("initializing " + this.entity.getEntity().toString());
+		}
+		//
+		// Iterate any existing values
+		//
+		Set<PIPConfigParam> unneeded = new HashSet<PIPConfigParam>();
+		for (PIPConfigParam param : this.entity.getEntity().getPipconfigParams()) {
+			if (param.getParamName().equals(LDAP_CONTEXT)) {
+				this.textFieldFactory.setData(param);
+			} else if (param.getParamName().equals(LDAP_URL)) {
+				this.textFieldProviderURL.setData(param);
+			} else if (param.getParamName().equals(LDAP_AUTH)) {
+				this.comboBoxAuthentication.setData(param);
+			} else if (param.getParamName().equals(LDAP_PRINCIPAL)) {
+				this.textFieldPrincipal.setData(param);
+			} else if (param.getParamName().equals(LDAP_CREDENTIALS)) {
+				this.textFieldCredentials.setData(param);
+			} else if (param.getParamName().equals(LDAP_SCOPE)) {
+				this.textFieldScope.setData(param);
+			} else {
+				unneeded.add(param);
+			}
+		}
+		//
+		// Get rid of unneeded parameters
+		//
+		if (unneeded.isEmpty() == false) {
+			this.entity.getEntity().getPipconfigParams().removeAll(unneeded);
+		}
+		//
+		// Initialize GUI
+		//
+		this.initializeEntity();
+		this.initializeCombo();
+		this.initializeText();
+		this.initializeButtons();
+	}
+	
+	protected void initializeEntity() {
+		//
+		// Initialize the entity
+		//
+		this.entity.getEntity().setClassname(CLASSNAME);
+		this.entity.getEntity().setRequiresResolvers(true);
+	}
+	
+	protected void initializeCombo() {
+		//
+		// GUI properties
+		//
+		this.comboBoxAuthentication.setImmediate(true);
+		this.comboBoxAuthentication.setNullSelectionAllowed(false);
+		this.comboBoxAuthentication.setRequired(true);
+		this.comboBoxAuthentication.setRequiredError("You must select an authentication mechanism");
+		//
+		// Initial set of items
+		//
+		this.comboBoxAuthentication.addItem(LDAP_AUTH_ANONYMOUS);
+		this.comboBoxAuthentication.addItem(LDAP_AUTH_SIMPLE);
+		this.comboBoxAuthentication.addItem(LDAP_AUTH_SASL);
+		//
+		// Ensure the authentication combo is selected to something.
+		//
+		PIPConfigParam param = (PIPConfigParam) this.comboBoxAuthentication.getData();
+		if (param == null) {
+			param = new PIPConfigParam(LDAP_AUTH, LDAP_AUTH_ANONYMOUS);
+			this.entity.getEntity().addPipconfigParam(param);
+			this.comboBoxAuthentication.setData(param);
+			this.comboBoxAuthentication.select(param.getParamValue());
+		} else {
+			//
+			// Is this custom?
+			//
+			this.comboBoxAuthentication.select(param.getParamValue());
+			if (this.comboBoxAuthentication.getValue().equals(param.getParamValue()) == false) {
+				this.comboBoxAuthentication.addItem(param.getParamValue());
+				this.comboBoxAuthentication.select(param.getParamValue());
+			}
+		}
+		//
+		// Respond to events
+		//
+		this.comboBoxAuthentication.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				PIPConfigParam param = (PIPConfigParam) self.comboBoxAuthentication.getData();
+				if (param == null) {
+					param = new PIPConfigParam(LDAP_AUTH, self.comboBoxAuthentication.getValue().toString());
+					self.entity.getEntity().addPipconfigParam(param);
+					self.comboBoxAuthentication.setData(param);
+				}
+				param.setParamValue(self.comboBoxAuthentication.getValue().toString());
+				self.fireFormChangedEvent();
+			}		
+		});
+	}
+	
+	protected void initializeText() {
+		//
+		//
+		//
+		this.textFieldFactory.setImmediate(true);
+		this.textFieldFactory.setNullRepresentation("");
+		//
+		// We can initialize this if there is no value
+		//
+		PIPConfigParam param = (PIPConfigParam) this.textFieldFactory.getData();
+		if (param == null) {
+			param = new PIPConfigParam(LDAP_CONTEXT, LDAP_DEFAULT_CONTEXT);
+			this.entity.getEntity().addPipconfigParam(param);
+			this.textFieldFactory.setData(param);
+		}
+		this.textFieldFactory.setValue(param.getParamValue());
+		this.textFieldFactory.addTextChangeListener(new TextChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void textChange(TextChangeEvent event) {
+				PIPConfigParam param = (PIPConfigParam) self.textFieldFactory.getData();
+				if (param == null) {
+					param = new PIPConfigParam(LDAP_CONTEXT);
+					self.entity.getEntity().addPipconfigParam(param);
+					self.textFieldFactory.setData(param);
+				}
+				param.setParamValue(self.textFieldFactory.getValue());
+				self.fireFormChangedEvent();
+			}
+		});
+		this.textFieldFactory.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				PIPConfigParam param = (PIPConfigParam) self.textFieldFactory.getData();
+				if (param == null) {
+					param = new PIPConfigParam(LDAP_CONTEXT);
+					self.entity.getEntity().addPipconfigParam(param);
+					self.textFieldFactory.setData(param);
+				}
+				param.setParamValue(self.textFieldFactory.getValue());
+				self.fireFormChangedEvent();
+			}
+		});
+		//
+		//
+		//
+		this.textFieldProviderURL.setImmediate(true);
+		this.textFieldProviderURL.setNullRepresentation("");
+		param = (PIPConfigParam) this.textFieldProviderURL.getData();
+		if (param != null) {
+			this.textFieldProviderURL.setValue(param.getParamValue());
+		}		
+		this.textFieldProviderURL.addTextChangeListener(new TextChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void textChange(TextChangeEvent event) {
+				PIPConfigParam param = (PIPConfigParam) self.textFieldProviderURL.getData();
+				if (param == null) {
+					param = new PIPConfigParam(LDAP_URL);
+					self.entity.getEntity().addPipconfigParam(param);
+					self.textFieldProviderURL.setData(param);
+				}
+				param.setParamValue(self.textFieldProviderURL.getValue());
+				self.fireFormChangedEvent();
+			}			
+		});
+		this.textFieldProviderURL.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				PIPConfigParam param = (PIPConfigParam) self.textFieldProviderURL.getData();
+				if (param == null) {
+					param = new PIPConfigParam(LDAP_URL);
+					self.entity.getEntity().addPipconfigParam(param);
+					self.textFieldProviderURL.setData(param);
+				}
+				param.setParamValue(self.textFieldProviderURL.getValue());
+				self.fireFormChangedEvent();
+			}			
+		});
+		//
+		//
+		//
+		this.textFieldPrincipal.setImmediate(true);
+		this.textFieldPrincipal.setNullRepresentation("");
+		param = (PIPConfigParam) this.textFieldPrincipal.getData();
+		if (param != null) {
+			this.textFieldPrincipal.setValue(param.getParamValue());
+		}		
+		this.textFieldPrincipal.addTextChangeListener(new TextChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void textChange(TextChangeEvent event) {
+				PIPConfigParam param = (PIPConfigParam) self.textFieldPrincipal.getData();
+				if (param == null) {
+					param = new PIPConfigParam(LDAP_PRINCIPAL);
+					self.entity.getEntity().addPipconfigParam(param);
+					self.textFieldPrincipal.setData(param);
+				}
+				param.setParamValue(self.textFieldPrincipal.getValue());
+				self.fireFormChangedEvent();
+			}			
+		});
+		this.textFieldPrincipal.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				PIPConfigParam param = (PIPConfigParam) self.textFieldPrincipal.getData();
+				if (param == null) {
+					param = new PIPConfigParam(LDAP_PRINCIPAL);
+					self.entity.getEntity().addPipconfigParam(param);
+					self.textFieldPrincipal.setData(param);
+				}
+				param.setParamValue(self.textFieldPrincipal.getValue());
+				self.fireFormChangedEvent();
+			}			
+		});
+		//
+		//
+		//
+		this.textFieldCredentials.setNullRepresentation("");
+		param = (PIPConfigParam) this.textFieldCredentials.getData();
+		if (param != null) {
+			this.textFieldCredentials.setValue(param.getParamValue());
+		}		
+		this.textFieldCredentials.addTextChangeListener(new TextChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void textChange(TextChangeEvent event) {
+				PIPConfigParam param = (PIPConfigParam) self.textFieldCredentials.getData();
+				if (param == null) {
+					param = new PIPConfigParam(LDAP_CREDENTIALS);
+					self.entity.getEntity().addPipconfigParam(param);
+					self.textFieldCredentials.setData(param);
+				}
+				param.setParamValue(self.textFieldCredentials.getValue());
+				self.fireFormChangedEvent();
+			}			
+		});
+		this.textFieldCredentials.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				PIPConfigParam param = (PIPConfigParam) self.textFieldCredentials.getData();
+				if (param == null) {
+					param = new PIPConfigParam(LDAP_CREDENTIALS);
+					self.entity.getEntity().addPipconfigParam(param);
+					self.textFieldCredentials.setData(param);
+				}
+				param.setParamValue(self.textFieldCredentials.getValue());
+				self.fireFormChangedEvent();
+			}			
+		});
+		//
+		//
+		//
+		this.textFieldScope.setNullRepresentation("");
+		param = (PIPConfigParam) this.textFieldScope.getData();
+		if (param == null) {
+			param = new PIPConfigParam(LDAP_SCOPE, "subtree");
+			this.entity.getEntity().addPipconfigParam(param);
+			this.textFieldScope.setData(param);
+		}
+		this.textFieldScope.setValue(param.getParamValue());
+		this.textFieldScope.addTextChangeListener(new TextChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void textChange(TextChangeEvent event) {
+				PIPConfigParam param = (PIPConfigParam) self.textFieldScope.getData();
+				if (param == null) {
+					param = new PIPConfigParam(LDAP_SCOPE);
+					self.entity.getEntity().addPipconfigParam(param);
+					self.textFieldScope.setData(param);
+				}
+				param.setParamValue(self.textFieldScope.getValue());
+				self.fireFormChangedEvent();
+			}			
+		});
+		this.textFieldScope.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				PIPConfigParam param = (PIPConfigParam) self.textFieldScope.getData();
+				if (param == null) {
+					param = new PIPConfigParam(LDAP_SCOPE);
+					self.entity.getEntity().addPipconfigParam(param);
+					self.textFieldScope.setData(param);
+				}
+				param.setParamValue(self.textFieldScope.getValue());
+				self.fireFormChangedEvent();
+			}			
+		});
+	}
+	
+	protected void initializeButtons() {
+		this.buttonTest.setImmediate(true);
+		this.buttonTest.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.testLDAPConnection();
+			}
+		});
+	}
+	
+	protected void testLDAPConnection() {
+		Hashtable<String, String> env = new Hashtable<String, String>();
+		env.put(Context.INITIAL_CONTEXT_FACTORY, this.textFieldFactory.getValue());
+		env.put(Context.PROVIDER_URL, this.textFieldProviderURL.getValue());
+		env.put(Context.SECURITY_PRINCIPAL, this.textFieldPrincipal.getValue());
+		env.put(Context.SECURITY_CREDENTIALS, this.textFieldCredentials.getValue());
+
+		String auth = this.comboBoxAuthentication.getValue().toString();
+		env.put(Context.SECURITY_AUTHENTICATION, auth);
+		//
+		// Do we need to do anything?
+		//
+		/*
+		if (auth.equals(LDAP_AUTH_ANONYMOUS)) {
+			
+		} else if (auth.equals(LDAP_AUTH_SIMPLE)) {
+			
+		} else if (auth.equals(LDAP_AUTH_SASL)) {
+			
+		}
+		*/
+
+		DirContext ctx = null;
+		try {
+		   ctx = new InitialDirContext(env);
+			new Notification("Success!",
+				    "Connection Established!",
+				    Type.HUMANIZED_MESSAGE, true)
+				    .show(Page.getCurrent());			
+		} catch (NamingException e) {
+		   logger.error(e);
+			new Notification("Connection Failed",
+				    "<br/>" + e.getLocalizedMessage(),
+				    Type.ERROR_MESSAGE, true)
+				    .show(Page.getCurrent());
+		} finally {
+			try {
+				if (ctx != null) {
+					ctx.close();
+				}
+			} catch (NamingException idontcare) { //NOPMD
+			}
+		}
+	}
+	
+	public void validate() throws InvalidValueException {
+		if (logger.isDebugEnabled()) {
+			logger.debug("validate");
+		}
+		this.comboBoxAuthentication.validate();
+		this.textFieldFactory.validate();
+		this.textFieldProviderURL.validate();
+		this.textFieldPrincipal.validate();
+		this.textFieldCredentials.validate();
+		this.textFieldScope.validate();
+	}
+
+	public void commit() throws SourceException, InvalidValueException {
+		if (logger.isDebugEnabled()) {
+			logger.debug("commit");
+		}
+		this.comboBoxAuthentication.commit();
+		this.textFieldFactory.commit();
+		this.textFieldProviderURL.commit();
+		this.textFieldPrincipal.commit();
+		this.textFieldCredentials.commit();
+		this.textFieldScope.commit();
+	}
+	
+	public void discard() throws SourceException {
+		if (logger.isDebugEnabled()) {
+			logger.debug("discard");
+		}
+		
+		this.textFieldFactory.discard();
+		this.textFieldProviderURL.discard();
+		this.textFieldPrincipal.discard();
+		this.textFieldCredentials.discard();
+		this.textFieldScope.discard();
+		/*
+		this.entity.getEntity().getPipconfigParams().remove(LDAP_CONTEXT);
+		this.entity.getEntity().getPipconfigParams().remove(LDAP_URL);
+		this.entity.getEntity().getPipconfigParams().remove(LDAP_AUTH);
+		this.entity.getEntity().getPipconfigParams().remove(LDAP_PRINCIPAL);
+		this.entity.getEntity().getPipconfigParams().remove(LDAP_CREDENTIALS);
+		this.entity.getEntity().getPipconfigParams().remove(LDAP_SCOPE);
+		*/
+	}
+
+	@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");
+		
+		// textFieldFactory
+		textFieldFactory = new TextField();
+		textFieldFactory.setCaption("Initial Context Factory");
+		textFieldFactory.setImmediate(false);
+		textFieldFactory.setWidth("-1px");
+		textFieldFactory.setHeight("-1px");
+		textFieldFactory.setInvalidAllowed(false);
+		textFieldFactory.setRequired(true);
+		textFieldFactory.setInputPrompt("com.sun.jndi.ldap.LdapCtxFactory");
+		mainLayout.addComponent(textFieldFactory);
+		mainLayout.setExpandRatio(textFieldFactory, 1.0f);
+		
+		// textFieldProviderURL
+		textFieldProviderURL = new TextField();
+		textFieldProviderURL.setCaption("Provider URL");
+		textFieldProviderURL.setImmediate(false);
+		textFieldProviderURL.setWidth("-1px");
+		textFieldProviderURL.setHeight("-1px");
+		textFieldProviderURL.setInvalidAllowed(false);
+		textFieldProviderURL.setRequired(true);
+		textFieldProviderURL
+				.setInputPrompt("Eg. ldap://localhost:389/o=JNDITutorial");
+		mainLayout.addComponent(textFieldProviderURL);
+		mainLayout.setExpandRatio(textFieldProviderURL, 1.0f);
+		
+		// comboBoxAuthentication
+		comboBoxAuthentication = new ComboBox();
+		comboBoxAuthentication.setCaption("Authentication");
+		comboBoxAuthentication.setImmediate(false);
+		comboBoxAuthentication.setWidth("-1px");
+		comboBoxAuthentication.setHeight("-1px");
+		comboBoxAuthentication.setRequired(true);
+		mainLayout.addComponent(comboBoxAuthentication);
+		mainLayout.setExpandRatio(comboBoxAuthentication, 1.0f);
+		
+		// textFieldPrincipal
+		textFieldPrincipal = new TextField();
+		textFieldPrincipal.setCaption("Principal");
+		textFieldPrincipal.setImmediate(false);
+		textFieldPrincipal.setWidth("-1px");
+		textFieldPrincipal.setHeight("-1px");
+		textFieldPrincipal.setNullSettingAllowed(true);
+		mainLayout.addComponent(textFieldPrincipal);
+		mainLayout.setExpandRatio(textFieldPrincipal, 1.0f);
+		
+		// textFieldCredentials
+		textFieldCredentials = new TextField();
+		textFieldCredentials.setCaption("Credentials");
+		textFieldCredentials.setImmediate(false);
+		textFieldCredentials.setWidth("-1px");
+		textFieldCredentials.setHeight("-1px");
+		textFieldCredentials.setNullSettingAllowed(true);
+		mainLayout.addComponent(textFieldCredentials);
+		mainLayout.setExpandRatio(textFieldCredentials, 1.0f);
+		
+		// textFieldScope
+		textFieldScope = new TextField();
+		textFieldScope.setCaption("Scope");
+		textFieldScope.setImmediate(false);
+		textFieldScope.setWidth("-1px");
+		textFieldScope.setHeight("-1px");
+		textFieldScope.setInvalidAllowed(false);
+		textFieldScope.setRequired(true);
+		textFieldScope.setInputPrompt("Eg. subtree");
+		mainLayout.addComponent(textFieldScope);
+		
+		// buttonTest
+		buttonTest = new Button();
+		buttonTest.setCaption("Test Connection");
+		buttonTest.setImmediate(true);
+		buttonTest.setWidth("-1px");
+		buttonTest.setHeight("-1px");
+		mainLayout.addComponent(buttonTest);
+		mainLayout.setComponentAlignment(buttonTest, new Alignment(48));
+		
+		return mainLayout;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/648d0c0d/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/OaExpressionsEditorComponent.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/OaExpressionsEditorComponent.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/OaExpressionsEditorComponent.java
new file mode 100644
index 0000000..bcbeca8
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/OaExpressionsEditorComponent.java
@@ -0,0 +1,186 @@
+/*
+ *  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.components;
+
+import org.apache.openaz.xacml.admin.jpa.Obadvice;
+import org.apache.openaz.xacml.admin.jpa.ObadviceExpression;
+import org.apache.openaz.xacml.admin.view.windows.ExpressionEditorWindow;
+import com.vaadin.addon.jpacontainer.EntityItem;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.util.filter.Compare;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+
+public class OaExpressionsEditorComponent extends CustomComponent {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private HorizontalLayout horizontalLayout_1;
+	@AutoGenerated
+	private Button buttonRemove;
+	@AutoGenerated
+	private Button buttonadd;
+	@AutoGenerated
+	private Table tableExpressions;
+	private static final long serialVersionUID = 1L;
+	private final OaExpressionsEditorComponent self = this;
+	private final JPAContainer<ObadviceExpression> container;
+	private final EntityItem<Obadvice> oa;
+	
+	/**
+	 * 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 OaExpressionsEditorComponent(EntityItem<Obadvice> oa, JPAContainer<ObadviceExpression> container) {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Save
+		//
+		this.container = container;
+		this.oa = oa;
+		//
+		// Filter the container
+		//
+		this.container.removeAllContainerFilters();
+		this.container.addContainerFilter(new Compare.Equal("obadvice", this.oa.getEntity()));
+		//
+		// Initialize components
+		//
+		this.initializeTable();
+		this.initializeButtons();
+	}
+	
+	private void initializeTable() {
+		this.tableExpressions.setContainerDataSource(this.container);
+		this.tableExpressions.setVisibleColumns(new Object[] {"type"});
+		this.tableExpressions.setColumnHeaders(new String[] {"Expression Type"});
+		this.tableExpressions.setPageLength(this.container.size() + 1);
+	}
+	
+	private void initializeButtons() {
+		this.buttonadd.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				ObadviceExpression expression = new ObadviceExpression();
+				// TODO - EntityItem is not used - does container.createEntityItem even need to be called?
+				// final EntityItem<ObadviceExpression> entity = self.container.createEntityItem(expression);
+				self.container.createEntityItem(expression); // See TODO
+
+				final ExpressionEditorWindow editor = new ExpressionEditorWindow();
+				editor.setCaption("Edit Attribute");
+				editor.setCloseShortcut(KeyCode.ESCAPE);
+				editor.setModal(true);
+				editor.center();
+				UI.getCurrent().addWindow(editor);
+			}
+			
+		});
+		this.buttonRemove.setEnabled(false);
+		this.buttonRemove.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.tableExpressions.removeItem(self.tableExpressions.getValue());
+			}
+			
+		});
+
+	}
+
+	@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");
+		
+		// tableExpressions
+		tableExpressions = new Table();
+		tableExpressions.setCaption("Expressions");
+		tableExpressions.setImmediate(false);
+		tableExpressions
+				.setDescription("The list of expressions for the obligation/advice object.");
+		tableExpressions.setWidth("-1px");
+		tableExpressions.setHeight("-1px");
+		mainLayout.addComponent(tableExpressions);
+		
+		// horizontalLayout_1
+		horizontalLayout_1 = buildHorizontalLayout_1();
+		mainLayout.addComponent(horizontalLayout_1);
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayout_1() {
+		// common part: create layout
+		horizontalLayout_1 = new HorizontalLayout();
+		horizontalLayout_1.setImmediate(false);
+		horizontalLayout_1.setWidth("-1px");
+		horizontalLayout_1.setHeight("-1px");
+		horizontalLayout_1.setMargin(false);
+		horizontalLayout_1.setSpacing(true);
+		
+		// buttonadd
+		buttonadd = new Button();
+		buttonadd.setCaption("Add");
+		buttonadd.setImmediate(true);
+		buttonadd.setWidth("-1px");
+		buttonadd.setHeight("-1px");
+		horizontalLayout_1.addComponent(buttonadd);
+		
+		// buttonRemove
+		buttonRemove = new Button();
+		buttonRemove.setCaption("Remove");
+		buttonRemove.setImmediate(true);
+		buttonRemove.setDescription("Remove selected expression(s).");
+		buttonRemove.setWidth("-1px");
+		buttonRemove.setHeight("-1px");
+		horizontalLayout_1.addComponent(buttonRemove);
+		
+		return horizontalLayout_1;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/648d0c0d/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/PIPParameterComponent.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/PIPParameterComponent.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/PIPParameterComponent.java
new file mode 100644
index 0000000..5a91ff2
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/PIPParameterComponent.java
@@ -0,0 +1,453 @@
+/*
+ *  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.components;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.jpa.PIPConfigParam;
+import org.apache.openaz.xacml.admin.jpa.PIPConfiguration;
+import org.apache.openaz.xacml.admin.jpa.PIPResolver;
+import org.apache.openaz.xacml.admin.jpa.PIPResolverParam;
+import org.apache.openaz.xacml.admin.view.events.FormChangedEventListener;
+import org.apache.openaz.xacml.admin.view.events.FormChangedEventNotifier;
+import org.apache.openaz.xacml.admin.view.windows.PIPParamEditorWindow;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+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.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+
+public class PIPParameterComponent extends CustomComponent implements FormChangedEventNotifier {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Table tableParameters;
+	@AutoGenerated
+	private HorizontalLayout horizontalLayout_1;
+	@AutoGenerated
+	private Button buttonClear;
+	@AutoGenerated
+	private Button buttonClone;
+	@AutoGenerated
+	private Button buttonRemove;
+	@AutoGenerated
+	private Button buttonAdd;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(PIPParameterComponent.class);
+	private final PIPParameterComponent self = this;
+	private final Object config;
+	private final BasicNotifier notifier = new BasicNotifier();
+	
+	private static final Action ADD_PARAM = 	new Action ("Add Parameter");
+	private static final Action EDIT_PARAM = 	new Action ("Edit Parameter");
+	private static final Action REMOVE_PARAM = 	new Action ("Remove Parameter");
+	private static final Action CLONE_PARAM = 	new Action ("Clone Parameter");
+
+	/**
+	 * 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 PIPParameterComponent(Object config) {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Save
+		//
+		this.config = config;
+		//
+		// Initialize
+		//
+		this.initializeTable();
+		this.initializeButtons();
+		//
+		// Initial button setup
+		//
+		this.setupButtons();
+	}
+	
+	protected void initializeTable() {
+		//
+		// Initialize GUI properties
+		//
+		this.tableParameters.setImmediate(true);
+		this.tableParameters.setSelectable(true);
+		//
+		// Add in the data
+		//
+		if (this.config instanceof PIPConfiguration) {
+			BeanItemContainer<PIPConfigParam> container = new BeanItemContainer<PIPConfigParam>(PIPConfigParam.class);
+			PIPConfiguration config = (PIPConfiguration) this.config;
+			for (PIPConfigParam param : config.getPipconfigParams()) {
+				container.addBean(param);
+			}
+			this.tableParameters.setContainerDataSource(container);
+		} else if (this.config instanceof PIPResolver) {
+			BeanItemContainer<PIPResolverParam> container = new BeanItemContainer<PIPResolverParam>(PIPResolverParam.class);
+			PIPResolver resolver = (PIPResolver) this.config;
+			for (PIPResolverParam param : resolver.getPipresolverParams()) {
+				container.addBean(param);
+			}
+			this.tableParameters.setContainerDataSource(container);
+		} else {
+			throw new IllegalArgumentException("Unsupported object");
+		}
+		//
+		// Finish more gui initialization
+		//
+		this.tableParameters.setPageLength(5);//this.tableParameters.getContainerDataSource().size() + 1);
+		this.tableParameters.setVisibleColumns(new Object[] {"paramName", "paramValue"});
+		this.tableParameters.setColumnHeaders(new String[] {"Name", "Value"});
+		this.tableParameters.setSizeFull();
+		//
+		// Action Handler
+		//
+		this.tableParameters.addActionHandler(new Handler() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Action[] getActions(Object target, Object sender) {
+				if (target == null) {
+					return new Action[] {ADD_PARAM};
+				}
+				return new Action[] {EDIT_PARAM, REMOVE_PARAM, CLONE_PARAM};
+			}
+
+			@Override
+			public void handleAction(Action action, Object sender, Object target) {
+				if (action == ADD_PARAM) {
+					self.editParameter(null);
+					return;
+				}
+				if (action == EDIT_PARAM) {
+					self.editParameter(target);
+					return;
+				}
+				if (action == REMOVE_PARAM) {
+					self.removeParameter(target);
+					return;
+				}
+				if (action == CLONE_PARAM) {
+					self.cloneParameter(target);
+					return;
+				}
+			}
+		});
+		//
+		// Respond to events
+		//
+		this.tableParameters.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.setupButtons();
+			}
+		});
+		//
+		// Double click
+		//
+		this.tableParameters.addItemClickListener(new ItemClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void itemClick(ItemClickEvent event) {
+				if (event.isDoubleClick()) {
+					self.editParameter(event.getItemId());
+				}
+			}
+		});
+	}
+	
+	protected void initializeButtons() {
+		this.buttonAdd.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.editParameter(null);
+			}
+		});
+		this.buttonClone.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.cloneParameter(self.tableParameters.getValue());
+			}
+		});
+		this.buttonRemove.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.removeParameter(self.tableParameters.getValue());
+			}
+		});
+		this.buttonClear.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.clearParameters();
+			}
+		});
+	}
+	
+	protected void setupButtons() {
+		if (this.tableParameters.getValue() != null) {
+			this.buttonClone.setEnabled(true);
+			this.buttonRemove.setEnabled(true);
+		} else {
+			this.buttonClone.setEnabled(false);
+			this.buttonRemove.setEnabled(false);
+		}
+	}
+
+	protected void editParameter(final Object source) {
+		//
+		// Make a copy
+		//
+		final Object target = source != null ? source : this.config instanceof PIPConfiguration ? new PIPConfigParam() : new PIPResolverParam();
+		final PIPParamEditorWindow window = new PIPParamEditorWindow(target);
+		window.setModal(true);
+		window.setCaption((source == null ? "Create New Parameter" : "Edit Parameter"));
+		window.center();
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did user save?
+				//
+				if (window.isSaved() == false) {
+					return;
+				}
+				//
+				// Yes - was it a brand new object?
+				//
+				if (source == null) {
+					//
+					// yes add it to the parent object
+					//
+					if (self.config instanceof PIPConfiguration) {
+						((PIPConfiguration) self.config).addPipconfigParam((PIPConfigParam) target);
+					} else {
+						((PIPResolver) self.config).addPipresolverParam((PIPResolverParam) target);
+					}
+					//
+					// add it to the table
+					//
+					Item item = self.tableParameters.addItem(target);
+					if (item == null) {
+						logger.error("Failed to add parameter: " + target);
+					} else {
+						self.tableParameters.select(target);
+					}
+				} else {
+					//
+					// Copy the parameters over
+					//
+					if (source instanceof PIPConfigParam) {
+						((PIPConfigParam) source).setParamName(((PIPConfigParam) target).getParamName());
+						((PIPConfigParam) source).setParamValue(((PIPConfigParam) target).getParamValue());
+					} else {
+						((PIPResolverParam) source).setParamName(((PIPResolverParam) target).getParamName());
+						((PIPResolverParam) source).setParamValue(((PIPResolverParam) target).getParamValue());
+					}
+					//
+					// Update the table
+					//
+					self.tableParameters.refreshRowCache();
+				}
+			}
+		});
+		UI.getCurrent().addWindow(window);
+	}
+
+	protected void cloneParameter(Object target) {
+		if (target == null) {
+			logger.error("null target sent to clone method");
+			return;
+		}
+		Item item;
+		if (target instanceof PIPConfigParam && this.config instanceof PIPConfiguration) {
+			PIPConfigParam param = new PIPConfigParam((PIPConfigParam) target);
+			((PIPConfiguration) this.config).addPipconfigParam(param);
+			item = this.tableParameters.addItem(new BeanItem<PIPConfigParam>(param));
+		} else if (target instanceof PIPResolverParam && this.config instanceof PIPResolver) {
+			PIPResolverParam param = new PIPResolverParam((PIPResolverParam) target);
+			((PIPResolver) this.config).addPipresolverParam(param);
+			item = this.tableParameters.addItem(new BeanItem<PIPResolverParam>(param));
+		} else {
+			throw new IllegalArgumentException("Unsupported param and config combination.");
+		}
+		if (item == null) {
+			logger.error("Failed to add parameter to table: " + target);
+		} else {
+			this.tableParameters.select(target);
+		}
+	}
+
+	protected void removeParameter(Object target) {
+		if (target == null) {
+			logger.error("null target sent to remove method");
+			return;
+		}
+		if (this.config instanceof PIPConfiguration) {
+			if (((PIPConfiguration)this.config).removePipconfigParam((PIPConfigParam) target) == null) {
+				logger.error("Failed to remove parameter from pip configuration");
+				return;
+			}
+		} else {
+			if (((PIPResolver) this.config).removePipresolverParam((PIPResolverParam) target) == null) {
+				logger.error("Failed to remove parameter from pip resolver");
+				return;
+			}
+		}
+		if (this.tableParameters.removeItem(target) == false) {
+			logger.error("Failed to remove parameter from table");
+		}
+	}
+	
+	protected void clearParameters() {
+		this.tableParameters.removeAllItems();
+		if (this.config instanceof PIPConfiguration) {
+			((PIPConfiguration) this.config).clearConfigParams();
+		} else {
+			((PIPResolver) this.config).clearParams();
+		}
+	}
+
+	@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(false);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("-1px");
+		setHeight("-1px");
+		
+		// horizontalLayout_1
+		horizontalLayout_1 = buildHorizontalLayout_1();
+		mainLayout.addComponent(horizontalLayout_1);
+		
+		// tableParameters
+		tableParameters = new Table();
+		tableParameters.setCaption("Configuration Parameters");
+		tableParameters.setImmediate(false);
+		tableParameters.setWidth("-1px");
+		tableParameters.setHeight("-1px");
+		mainLayout.addComponent(tableParameters);
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayout_1() {
+		// common part: create layout
+		horizontalLayout_1 = new HorizontalLayout();
+		horizontalLayout_1.setImmediate(false);
+		horizontalLayout_1.setWidth("-1px");
+		horizontalLayout_1.setHeight("-1px");
+		horizontalLayout_1.setMargin(false);
+		horizontalLayout_1.setSpacing(true);
+		
+		// buttonAdd
+		buttonAdd = new Button();
+		buttonAdd.setCaption("Add");
+		buttonAdd.setImmediate(false);
+		buttonAdd.setWidth("-1px");
+		buttonAdd.setHeight("-1px");
+		horizontalLayout_1.addComponent(buttonAdd);
+		
+		// buttonRemove
+		buttonRemove = new Button();
+		buttonRemove.setCaption("Remove");
+		buttonRemove.setImmediate(false);
+		buttonRemove.setWidth("-1px");
+		buttonRemove.setHeight("-1px");
+		horizontalLayout_1.addComponent(buttonRemove);
+		
+		// buttonClone
+		buttonClone = new Button();
+		buttonClone.setCaption("Clone");
+		buttonClone.setImmediate(false);
+		buttonClone.setWidth("-1px");
+		buttonClone.setHeight("-1px");
+		horizontalLayout_1.addComponent(buttonClone);
+		
+		// buttonClear
+		buttonClear = new Button();
+		buttonClear.setCaption("Clear All");
+		buttonClear.setImmediate(false);
+		buttonClear.setWidth("-1px");
+		buttonClear.setHeight("-1px");
+		horizontalLayout_1.addComponent(buttonClear);
+		
+		return horizontalLayout_1;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/648d0c0d/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/PIPResolverComponent.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/PIPResolverComponent.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/PIPResolverComponent.java
new file mode 100644
index 0000000..7529e70
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/PIPResolverComponent.java
@@ -0,0 +1,275 @@
+/*
+ *  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.components;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+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.PIPResolver;
+import org.apache.openaz.xacml.admin.view.windows.PIPResolverEditorWindow;
+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.vaadin.addon.jpacontainer.EntityItem;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.addon.jpacontainer.provider.CachingMutableLocalEntityProvider;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.util.filter.Compare;
+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.CustomComponent;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+
+public class PIPResolverComponent extends CustomComponent {
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Table tableResolvers;
+	
+	private final Action ADD_RESOLVER = new Action("Add Resolver");
+	private final Action EDIT_RESOLVER = new Action("Edit Resolver");
+	private final Action CLONE_RESOLVER = new Action("Clone Resolver");
+	private final Action REMOVE_RESOLVER = new Action("Remove Resolver");
+
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(PIPResolverComponent.class);
+	
+	private final PIPResolverComponent self = this;
+	private final PIPConfiguration config;
+	
+	private final JPAContainer<PIPResolver> resolverContainer = new JPAContainer<PIPResolver>(PIPResolver.class);
+
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 */
+	public PIPResolverComponent(PIPConfiguration configuration) {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Save
+		//
+		this.config = configuration;
+		this.resolverContainer.setEntityProvider(new CachingMutableLocalEntityProvider<PIPResolver>(PIPResolver.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+		this.resolverContainer.addContainerFilter(new Compare.Equal("pipconfiguration", this.config));
+		//
+		// Initialize GUI
+		//
+		this.initializeTable();
+	}
+	
+	protected void initializeTable() {
+		//
+		// Setup the container datasource
+		//
+		this.tableResolvers.setContainerDataSource(this.resolverContainer);
+		//
+		// Set GUI properties
+		//
+		this.tableResolvers.setImmediate(true);
+		this.tableResolvers.setVisibleColumns(new Object[] {"name", "description", "issuer"});
+		this.tableResolvers.setColumnHeaders(new String[] {"Name", "Description", "Issuer"});
+		this.tableResolvers.setPageLength(this.config.getPipresolvers().size() + 1);
+		this.tableResolvers.setSizeFull();
+		this.tableResolvers.setSelectable(true);
+		//
+		// Add the actions
+		//
+		this.tableResolvers.addActionHandler(new Handler() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Action[] getActions(Object target, Object sender) {
+				if (target == null) {
+					return new Action[] {ADD_RESOLVER};
+				}
+				return new Action[] {EDIT_RESOLVER, CLONE_RESOLVER, REMOVE_RESOLVER};
+			}
+
+			@Override
+			public void handleAction(Action action, Object sender, Object target) {
+				if (action == ADD_RESOLVER) {
+					PIPResolverComponent.addResolver(self.config, null);
+					return;
+				}
+				if (action == EDIT_RESOLVER) {
+					PIPResolverComponent.editResolver(self.resolverContainer.getItem(target));
+					return;
+				}
+				if (action == CLONE_RESOLVER) {
+					PIPResolverComponent.addResolver(self.config, self.resolverContainer.getItem(target).getEntity());
+					return;
+				}
+				if (action == REMOVE_RESOLVER) {
+					self.removeResolver(self.config, self.resolverContainer.getItem(target).getEntity());
+					return;
+				}
+			}
+		});
+		//
+		// Respond to events
+		//
+		this.tableResolvers.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) {
+						return;
+					}
+					PIPResolverComponent.editResolver(self.resolverContainer.getItem(id));
+				}
+			}
+		});
+	}
+	
+	protected void removeResolver(PIPConfiguration config, PIPResolver resolver) {
+		config.removePipresolver(resolver);
+		this.tableResolvers.removeItem(resolver.getId());
+	}
+
+	public static void	addResolver(PIPConfiguration config, PIPResolver pipResolver) {
+		//
+		// Create the entity
+		//
+		PIPResolver resolver = null;
+		if (pipResolver != null) {
+			resolver = new PIPResolver(pipResolver);
+		} else {
+			resolver = new PIPResolver();
+		}
+		resolver.setCreatedBy(((XacmlAdminUI)UI.getCurrent()).getUserid());
+		resolver.setModifiedBy(((XacmlAdminUI)UI.getCurrent()).getUserid());
+		resolver.setPipconfiguration(config);
+		//
+		// Set its default class
+		//
+		if (config.getPiptype().isSQL()) {
+			resolver.setClassname(ConfigurableJDBCResolver.class.getCanonicalName());
+		} else if (config.getPiptype().isLDAP()) {
+			resolver.setClassname(ConfigurableLDAPResolver.class.getCanonicalName());
+		} else if (config.getPiptype().isCSV()) {
+			resolver.setClassname(ConfigurableCSVResolver.class.getCanonicalName());
+		} else if (config.getPiptype().isHyperCSV()) {
+			resolver.setClassname(ConfigurableJDBCResolver.class.getCanonicalName());
+		}
+		//
+		// Bring up the editor window
+		//
+		PIPResolverComponent.editResolver(((XacmlAdminUI)UI.getCurrent()).getPIPResolvers().createEntityItem(resolver));
+		
+	}
+	
+	public static void	editResolver(final EntityItem<PIPResolver> entity) {
+		
+		final PIPResolverEditorWindow window = new PIPResolverEditorWindow(entity);
+		window.setModal(true);
+		window.center();
+		if (entity.isPersistent()) {
+			window.setCaption("Edit Resolver");
+		} else {
+			window.setCaption("Create Resolver");
+		}
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user click "save"?
+				//
+				if (window.isSaved() == false) {
+					return;
+				}
+				//
+				// Adding a new entity?
+				//
+				if (entity.isPersistent() == false) {
+					//
+					// Yes - let's official add it
+					//
+					((XacmlAdminUI)UI.getCurrent()).getPIPResolvers().addEntity(entity.getEntity());
+					((XacmlAdminUI)UI.getCurrent()).refreshPIPConfiguration();
+				}
+			}
+		});
+		UI.getCurrent().addWindow(window);
+	}
+
+	public static void publishConfiguration(EntityItem<PIPConfiguration> config) {
+		Properties properties = config.getEntity().generateProperties(Integer.toString(config.getEntity().getId()));
+		
+		try {
+			ByteArrayOutputStream os = new ByteArrayOutputStream();
+			properties.store(os, "");
+			if (logger.isDebugEnabled()) {
+				logger.debug(os.toString());
+			}
+		} catch (IOException e) { //NOPMD
+			// TODO - Handle, Log or NOPMD
+			// TODO - Will vaadin display error?
+		}
+	}
+		
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("-1px");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(false);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("-1px");
+		setHeight("-1px");
+		
+		// tableResolvers
+		tableResolvers = new Table();
+		tableResolvers.setCaption("Resolvers");
+		tableResolvers.setImmediate(false);
+		tableResolvers.setWidth("-1px");
+		tableResolvers.setHeight("-1px");
+		mainLayout.addComponent(tableResolvers);
+		
+		return mainLayout;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/648d0c0d/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/RangeEditorComponent.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/RangeEditorComponent.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/RangeEditorComponent.java
new file mode 100644
index 0000000..d07aa34
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/RangeEditorComponent.java
@@ -0,0 +1,599 @@
+/*
+ *  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.components;
+
+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.ConstraintValue;
+import org.apache.openaz.xacml.admin.util.AdminNotification;
+import org.apache.openaz.xacml.api.Identifier;
+import org.apache.openaz.xacml.api.XACML3;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.Validator;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.validator.DoubleRangeValidator;
+import com.vaadin.data.validator.IntegerRangeValidator;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+
+public class RangeEditorComponent extends CustomComponent {
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Panel panelTester;
+	@AutoGenerated
+	private VerticalLayout verticalLayout_2;
+	@AutoGenerated
+	private Button buttonValidate;
+	@AutoGenerated
+	private TextField textFieldTestInput;
+	@AutoGenerated
+	private HorizontalLayout horizontalLayout_2;
+	@AutoGenerated
+	private TextField textFieldMax;
+	@AutoGenerated
+	private ComboBox comboBoxMax;
+	@AutoGenerated
+	private HorizontalLayout horizontalLayout_1;
+	@AutoGenerated
+	private TextField textFieldMin;
+	@AutoGenerated
+	private ComboBox comboBoxMin;
+	private static final long serialVersionUID = -1L;
+	private static final Log logger	= LogFactory.getLog(RangeEditorComponent.class);
+	private final RangeEditorComponent self = this;
+	private final Attribute attribute;
+	private Identifier datatype;
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	public RangeEditorComponent(Attribute attribute, Identifier datatype) {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Save our attribute
+		//
+		this.attribute = attribute;
+		this.datatype = datatype;
+		//
+		// Finish initialization
+		//
+		this.initializeCombos();	
+		this.initializeTextFields();
+		this.initializeTest();
+		this.setupDatatype(this.datatype);
+	}
+	
+	private void initializeCombos() {
+		//
+		// Add the 2 possible values into each combo box
+		//
+		this.comboBoxMin.setNullSelectionAllowed(true);
+		this.comboBoxMin.addItem("minInclusive");
+		this.comboBoxMin.addItem("minExclusive");		
+		this.comboBoxMax.addItem("maxInclusive");
+		this.comboBoxMax.addItem("maxExclusive");
+		//
+		// Find any current values
+		//
+		for (ConstraintValue value : this.attribute.getConstraintValues()) {
+			if (value.getProperty().equals("minInclusive") ||
+				value.getProperty().equals("minExclusive")) {
+				//
+				// If it hasn't been set yet
+				//
+				if (this.comboBoxMin.getData() == null) {
+					//
+					// Select the appropriate combo value
+					//
+					this.comboBoxMin.select(value.getProperty());
+					//
+					// Save the object
+					//
+					this.comboBoxMin.setData(value);
+					//
+					// Setup the text field
+					//
+					this.textFieldMin.setValue(value.getValue());
+				} else {
+					//
+					// Extra value in there, this shouldn't happen. But this
+					// is here just in case
+					//
+					logger.warn("Extra min value found: " + value.getProperty() + " " + value.getValue());
+				}
+			} else if (value.getProperty().equals("maxInclusive") ||
+					value.getProperty().equals("maxExclusive")) {
+				//
+				// Check if it hasn't been set yet
+				//
+				if (this.comboBoxMax.getData() == null) {
+					//
+					// Select the appropriate combo value
+					//
+					this.comboBoxMax.select(value.getProperty());
+					//
+					// Save the object
+					//
+					this.comboBoxMax.setData(value);
+					//
+					// Setup the text field
+					//
+					this.textFieldMax.setValue(value.getValue());
+				} else {
+					//
+					// Extra value in there, this shouldn't happen. But this
+					// is here just in case
+					//
+					logger.warn("Extra max value found: " + value.getProperty() + " " + value.getValue());
+				}
+			} else {
+				logger.warn("Non-range value found: " + value.getProperty() + " " + value.getValue());
+			}
+		}
+		//
+		// Were there values?
+		//
+		if (this.comboBoxMin.getData() == null) {
+			//
+			// Put a new empty value in there
+			//
+			ConstraintValue value = new ConstraintValue("minInclusive", null);
+			//
+			// Associate it with the attribute
+			//
+			value.setAttribute(this.attribute);
+			//
+			// Make sure the attribute has it in its list
+			//
+			this.attribute.addConstraintValue(value);
+			//
+			// Save it in the combo
+			//
+			this.comboBoxMin.setData(value);
+			//
+			// Disable text field
+			//
+			this.textFieldMin.setEnabled(false);
+		}
+		if (this.comboBoxMax.getData() == null) {
+			//
+			// Put a new empty value in there
+			//
+			ConstraintValue value = new ConstraintValue("maxInclusive", null);
+			//
+			// Associate it with the attribute
+			//
+			value.setAttribute(this.attribute);
+			//
+			// Make sure the attribute has it in its list
+			//
+			this.attribute.addConstraintValue(value);
+			//
+			// Save it in the combo
+			//
+			this.comboBoxMax.setData(value);
+			//
+			// Disable text field
+			//
+			this.textFieldMax.setEnabled(false);
+		}
+		//
+		// Respond to combo changes
+		//
+		this.setupComboText(this.comboBoxMin, this.textFieldMin);
+		this.setupComboText(this.comboBoxMax, this.textFieldMax);
+	}
+	
+	private void setupComboText(final ComboBox box, final TextField text) {
+		//
+		// Respond to combo changes
+		//
+		box.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				//
+				// Get the new value
+				//
+				String property = (String) box.getValue();
+				//
+				// Get our constraint object
+				//
+				ConstraintValue value = (ConstraintValue) box.getData();
+				//
+				// Update our object
+				//
+				if (property == null) {
+					//
+					// Clear the text field and disable it
+					//
+					text.setEnabled(false);
+					text.setValue(null);
+				} else {
+					//
+					// Change the property name
+					//
+					value.setProperty(property);
+					//
+					// Focus to the text field and enable it
+					//
+					text.setEnabled(true);
+					text.focus();
+				}
+			}
+		});
+		
+	}
+	
+	private void initializeTextFields() {
+		this.textFieldMin.setNullRepresentation("");
+		this.textFieldMin.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				//
+				// Get our min object
+				//
+				ConstraintValue value = (ConstraintValue) self.comboBoxMin.getData();
+				//
+				// Save its new value
+				//
+				value.setValue(self.textFieldMin.getValue());
+			}			
+		});
+		this.textFieldMax.setNullRepresentation("");
+		this.textFieldMax.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				//
+				// Get our max object
+				//
+				ConstraintValue value = (ConstraintValue) self.comboBoxMax.getData();
+				//
+				// Save its new value
+				//
+				value.setValue(self.textFieldMax.getValue());
+			}
+			
+		});
+	}
+	
+	private void initializeTest() {
+		this.textFieldTestInput.setNullRepresentation("");
+		this.textFieldTestInput.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				if (self.textFieldTestInput.getValue() != null && self.textFieldTestInput.getValue().length() > 0) {
+					self.buttonValidate.setEnabled(true);
+				} else {
+					self.buttonValidate.setEnabled(false);
+				}
+			}
+		});
+				
+		this.buttonValidate.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				//
+				// Create our validator and add it into the text
+				//
+				Validator validator = self.setupValidator(self.datatype);
+				if (validator == null) {
+					logger.warn("Could not create a validator");
+					return;
+				}
+				self.textFieldTestInput.addValidator(validator);
+				//
+				// Initiate the validation
+				//
+				try {
+					self.textFieldTestInput.validate();
+					//
+					// If we get here, then it validated!
+					//
+					AdminNotification.info("Success! Value is in range");
+				} catch (InvalidValueException e) {
+					AdminNotification.warn("Failed, Value is NOT in range");
+				}
+				//
+				// Remove the validator
+				//
+				self.textFieldTestInput.removeValidator(validator);
+			}			
+		});
+	}
+	
+	private Validator setupValidator(Identifier id) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("setupValidator: " + id);
+		}
+		//
+		// Get our min/max objects
+		//
+		ConstraintValue min = (ConstraintValue) self.comboBoxMin.getData();
+		ConstraintValue max = (ConstraintValue) self.comboBoxMax.getData();
+		Object minObject = self.comboBoxMin.getConvertedValue();
+		Object maxObject = self.comboBoxMax.getConvertedValue();
+		logger.debug("Converted values: " + minObject + " " + maxObject);
+		//
+		// Get our min/max values
+		//
+		String minValue = self.textFieldMin.getValue();
+		String maxValue = self.textFieldMax.getValue();
+		//
+		// What is our datatype?
+		//
+		if (id.equals(XACML3.ID_DATATYPE_INTEGER)) {
+			Integer minimum = null;
+			Integer maximum = null;
+			boolean minInclusive = true;
+			boolean maxInclusive = true;
+			if (min.getProperty() != null) {
+				if (minValue != null && minValue.length() > 0) {
+					minimum = Integer.parseInt(minValue);
+				}
+				if (min.getProperty().equals("minInclusive")) {
+					minInclusive = true;
+				} else if (min.getProperty().equals("minExclusive")) {
+					minInclusive = false;
+				}
+			}
+			if (max.getProperty() != null) {
+				if (maxValue != null && maxValue.length() > 0) {
+					maximum = Integer.parseInt(maxValue);
+				}
+				if (max.getProperty().equals("maxInclusive")) {
+					maxInclusive = true;
+				} else if (max.getProperty().equals("maxExclusive")) {
+					maxInclusive = false;
+				}
+			}
+			IntegerRangeValidator validator = new IntegerRangeValidator("The value is NOT within the range", minimum, maximum);
+			validator.setMinValueIncluded(minInclusive);
+			validator.setMaxValueIncluded(maxInclusive);
+			return validator;
+		}
+		if (id.equals(XACML3.ID_DATATYPE_DOUBLE)) {
+			Double minimum = null;
+			Double maximum = null;
+			boolean minInclusive = true;
+			boolean maxInclusive = true;
+			if (min.getProperty() != null) {
+				if (minValue != null && minValue.length() > 0) {
+					minimum = Double.parseDouble(minValue);
+				}
+				if (min.getProperty().equals("minInclusive")) {
+					minInclusive = true;
+				} else if (min.getProperty().equals("minExclusive")) {
+					minInclusive = false;
+				}
+			}
+			if (max.getProperty() != null) {
+				if (maxValue != null && maxValue.length() > 0) {
+					maximum = Double.parseDouble(maxValue);
+				}
+				if (max.getProperty().equals("maxInclusive")) {
+					maxInclusive = true;
+				} else if (max.getProperty().equals("maxExclusive")) {
+					maxInclusive = false;
+				}
+			}
+			DoubleRangeValidator validator = new DoubleRangeValidator("The value is NOT within the range", minimum, maximum);
+			validator.setMinValueIncluded(minInclusive);
+			validator.setMaxValueIncluded(maxInclusive);
+			return validator;
+		}
+		
+		return null;
+	}
+	
+	public void	setupDatatype(Identifier datatype) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("setupDatatype: " + datatype);
+		}
+		this.datatype = datatype;
+		if (datatype.equals(XACML3.ID_DATATYPE_INTEGER)) {
+			this.textFieldMin.setConverter(Integer.class);
+			this.textFieldMax.setConverter(Integer.class);
+			this.textFieldTestInput.setConverter(Integer.class);
+			return;
+		}
+		if (datatype.equals(XACML3.ID_DATATYPE_DOUBLE)) {
+			this.textFieldMin.setConverter(Double.class);
+			this.textFieldMax.setConverter(Double.class);
+			this.textFieldTestInput.setConverter(Double.class);
+			return;
+		}
+	}
+
+	@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");
+		
+		// horizontalLayout_1
+		horizontalLayout_1 = buildHorizontalLayout_1();
+		mainLayout.addComponent(horizontalLayout_1);
+		mainLayout.setExpandRatio(horizontalLayout_1, 1.0f);
+		
+		// horizontalLayout_2
+		horizontalLayout_2 = buildHorizontalLayout_2();
+		mainLayout.addComponent(horizontalLayout_2);
+		mainLayout.setExpandRatio(horizontalLayout_2, 1.0f);
+		
+		// panelTester
+		panelTester = buildPanelTester();
+		mainLayout.addComponent(panelTester);
+		mainLayout.setExpandRatio(panelTester, 1.0f);
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayout_1() {
+		// common part: create layout
+		horizontalLayout_1 = new HorizontalLayout();
+		horizontalLayout_1.setImmediate(false);
+		horizontalLayout_1.setWidth("-1px");
+		horizontalLayout_1.setHeight("-1px");
+		horizontalLayout_1.setMargin(false);
+		horizontalLayout_1.setSpacing(true);
+		
+		// comboBoxMin
+		comboBoxMin = new ComboBox();
+		comboBoxMin.setCaption("Minimum Type");
+		comboBoxMin.setImmediate(true);
+		comboBoxMin.setDescription("Select the type for the minimum.");
+		comboBoxMin.setWidth("-1px");
+		comboBoxMin.setHeight("-1px");
+		horizontalLayout_1.addComponent(comboBoxMin);
+		
+		// textFieldMin
+		textFieldMin = new TextField();
+		textFieldMin.setCaption("Minimum Value");
+		textFieldMin.setImmediate(true);
+		textFieldMin.setDescription("Enter a value for the minimum.");
+		textFieldMin.setWidth("-1px");
+		textFieldMin.setHeight("-1px");
+		textFieldMin.setInvalidAllowed(false);
+		textFieldMin.setInputPrompt("eg. 1");
+		horizontalLayout_1.addComponent(textFieldMin);
+		horizontalLayout_1
+				.setComponentAlignment(textFieldMin, new Alignment(9));
+		
+		return horizontalLayout_1;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayout_2() {
+		// common part: create layout
+		horizontalLayout_2 = new HorizontalLayout();
+		horizontalLayout_2.setImmediate(false);
+		horizontalLayout_2.setWidth("-1px");
+		horizontalLayout_2.setHeight("-1px");
+		horizontalLayout_2.setMargin(false);
+		horizontalLayout_2.setSpacing(true);
+		
+		// comboBoxMax
+		comboBoxMax = new ComboBox();
+		comboBoxMax.setCaption("Maximum Type");
+		comboBoxMax.setImmediate(true);
+		comboBoxMax.setDescription("Select the type for the maximum.");
+		comboBoxMax.setWidth("-1px");
+		comboBoxMax.setHeight("-1px");
+		horizontalLayout_2.addComponent(comboBoxMax);
+		
+		// textFieldMax
+		textFieldMax = new TextField();
+		textFieldMax.setCaption("Maximum Value");
+		textFieldMax.setImmediate(true);
+		textFieldMax.setDescription("Enter a value for the maxmum.");
+		textFieldMax.setWidth("-1px");
+		textFieldMax.setHeight("-1px");
+		textFieldMax.setInvalidAllowed(false);
+		textFieldMax.setInputPrompt("eg. 100");
+		horizontalLayout_2.addComponent(textFieldMax);
+		
+		return horizontalLayout_2;
+	}
+
+	@AutoGenerated
+	private Panel buildPanelTester() {
+		// common part: create layout
+		panelTester = new Panel();
+		panelTester.setCaption("Test Range Values");
+		panelTester.setImmediate(true);
+		panelTester.setWidth("-1px");
+		panelTester.setHeight("-1px");
+		
+		// verticalLayout_2
+		verticalLayout_2 = buildVerticalLayout_2();
+		panelTester.setContent(verticalLayout_2);
+		
+		return panelTester;
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildVerticalLayout_2() {
+		// common part: create layout
+		verticalLayout_2 = new VerticalLayout();
+		verticalLayout_2.setImmediate(false);
+		verticalLayout_2.setWidth("100.0%");
+		verticalLayout_2.setHeight("100.0%");
+		verticalLayout_2.setMargin(false);
+		verticalLayout_2.setSpacing(true);
+		
+		// textFieldTestInput
+		textFieldTestInput = new TextField();
+		textFieldTestInput.setCaption("Value");
+		textFieldTestInput.setImmediate(true);
+		textFieldTestInput.setDescription("Enter a value to test against.");
+		textFieldTestInput.setWidth("-1px");
+		textFieldTestInput.setHeight("-1px");
+		textFieldTestInput.setInputPrompt("eg. 50");
+		verticalLayout_2.addComponent(textFieldTestInput);
+		
+		// buttonValidate
+		buttonValidate = new Button();
+		buttonValidate.setCaption("Test");
+		buttonValidate.setImmediate(true);
+		buttonValidate
+				.setDescription("Click to test if value is within the range.");
+		buttonValidate.setWidth("-1px");
+		buttonValidate.setHeight("-1px");
+		verticalLayout_2.addComponent(buttonValidate);
+		verticalLayout_2.setComponentAlignment(buttonValidate,
+				new Alignment(48));
+		
+		return verticalLayout_2;
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/648d0c0d/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/RegexpEditorComponent.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/RegexpEditorComponent.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/RegexpEditorComponent.java
new file mode 100644
index 0000000..968719a
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/components/RegexpEditorComponent.java
@@ -0,0 +1,246 @@
+/*
+ *  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.components;
+
+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.ConstraintType;
+import org.apache.openaz.xacml.admin.jpa.ConstraintValue;
+import org.apache.openaz.xacml.admin.util.AdminNotification;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.Validator;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.validator.RegexpValidator;
+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.CustomComponent;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+
+public class RegexpEditorComponent extends CustomComponent {
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+
+	@AutoGenerated
+	private Panel panelTester;
+
+	@AutoGenerated
+	private VerticalLayout verticalLayout_2;
+
+	@AutoGenerated
+	private Button buttonTest;
+
+	@AutoGenerated
+	private TextField textFieldTestValue;
+
+	@AutoGenerated
+	private TextField textFieldExpression;
+
+	private static final long serialVersionUID = -1L;
+	private static final Log logger	= LogFactory.getLog(RegexpEditorComponent.class);
+	private RegexpEditorComponent self = this;
+	private final Attribute attribute;
+	private ConstraintValue value = null;
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	public RegexpEditorComponent(Attribute attribute) {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		
+		this.attribute = attribute;
+		
+		initializeTextField();
+		initializeTestPanel();
+	}
+	
+	private void initializeTextField() {
+		//
+		// Find our reg expression value if it exists
+		//
+		for (ConstraintValue value : this.attribute.getConstraintValues()) {
+			if (value.getProperty().equals(ConstraintType.REGEXP_TYPE)) {
+				if (this.value == null) {
+					this.textFieldExpression.setValue(value.getValue());
+					this.value = value;
+				} else {
+					logger.warn("Multiple regexp constraint values: " + value);
+					value.setAttribute(null);
+					this.attribute.removeConstraintValue(value);
+				}
+			} else {
+				value.setAttribute(null);
+				this.attribute.removeConstraintValue(value);
+			}
+		}
+		//
+		// Was something found?
+		//
+		if (this.value == null) {
+			ConstraintValue newValue = new ConstraintValue(ConstraintType.REGEXP_TYPE, "");
+			newValue.setAttribute(this.attribute);
+			this.attribute.addConstraintValue(newValue);
+			this.value = newValue;
+		}
+		//
+		// Save the values when they changes
+		//
+		this.textFieldExpression.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.value.setValue(self.textFieldExpression.getValue());
+			}
+		});
+	}
+	
+	private void initializeTestPanel() {
+		this.textFieldTestValue.setNullRepresentation("");
+		
+		this.buttonTest.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				String testValue = self.textFieldTestValue.getValue();
+				if (testValue == null || testValue.length() == 0) {
+					return;
+				}
+				String regExp = self.textFieldExpression.getValue();
+				if (regExp == null || regExp.length() == 0) {
+					return;
+				}
+				//
+				// Create a validator
+				//
+				Validator validator = new RegexpValidator(regExp, true, "Regular Expression does NOT match.");
+				//
+				// Add it
+				//
+				self.textFieldTestValue.addValidator(validator);
+				//
+				// Validate
+				//
+				try {
+					self.textFieldTestValue.validate();
+					AdminNotification.info("Success! Regular Expression Matches");
+				} catch (InvalidValueException e) {
+					AdminNotification.warn("Failed, Regular Expression does NOT match");
+				}
+				//
+				// Remove the validator
+				//
+				self.textFieldTestValue.removeValidator(validator);
+			}
+		});
+	}
+	
+	@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");
+		
+		// textFieldExpression
+		textFieldExpression = new TextField();
+		textFieldExpression.setCaption("Regular Expression");
+		textFieldExpression.setImmediate(true);
+		textFieldExpression
+				.setDescription("Create a regular expression used to constrain attribute values.");
+		textFieldExpression.setWidth("-1px");
+		textFieldExpression.setHeight("-1px");
+		textFieldExpression.setInvalidAllowed(false);
+		textFieldExpression.setInputPrompt("eg. [a-zA-Z0-9]");
+		mainLayout.addComponent(textFieldExpression);
+		mainLayout.setExpandRatio(textFieldExpression, 1.0f);
+		
+		// panelTester
+		panelTester = buildPanelTester();
+		mainLayout.addComponent(panelTester);
+		mainLayout.setExpandRatio(panelTester, 1.0f);
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private Panel buildPanelTester() {
+		// common part: create layout
+		panelTester = new Panel();
+		panelTester.setCaption("Test The Expression");
+		panelTester.setImmediate(false);
+		panelTester.setWidth("-1px");
+		panelTester.setHeight("-1px");
+		
+		// verticalLayout_2
+		verticalLayout_2 = buildVerticalLayout_2();
+		panelTester.setContent(verticalLayout_2);
+		
+		return panelTester;
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildVerticalLayout_2() {
+		// common part: create layout
+		verticalLayout_2 = new VerticalLayout();
+		verticalLayout_2.setImmediate(false);
+		verticalLayout_2.setWidth("100.0%");
+		verticalLayout_2.setHeight("100.0%");
+		verticalLayout_2.setMargin(false);
+		
+		// textFieldTestValue
+		textFieldTestValue = new TextField();
+		textFieldTestValue.setCaption("Test Value");
+		textFieldTestValue.setImmediate(true);
+		textFieldTestValue
+				.setDescription("Enter a value to match against the regular expression.");
+		textFieldTestValue.setWidth("-1px");
+		textFieldTestValue.setHeight("-1px");
+		textFieldTestValue.setInputPrompt("eg. example");
+		verticalLayout_2.addComponent(textFieldTestValue);
+		
+		// buttonTest
+		buttonTest = new Button();
+		buttonTest.setCaption("Test");
+		buttonTest.setImmediate(true);
+		buttonTest.setWidth("-1px");
+		buttonTest.setHeight("-1px");
+		verticalLayout_2.addComponent(buttonTest);
+		verticalLayout_2.setComponentAlignment(buttonTest, new Alignment(48));
+		
+		return verticalLayout_2;
+	}
+}