| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| |
| package org.apache.openaz.xacml.admin.view.windows; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| import org.apache.openaz.xacml.admin.XacmlAdminUI; |
| import org.apache.openaz.xacml.admin.jpa.Attribute; |
| import org.apache.openaz.xacml.admin.jpa.ConstraintType; |
| import org.apache.openaz.xacml.admin.jpa.Datatype; |
| import org.apache.openaz.xacml.admin.view.fields.ConstraintField; |
| import org.apache.openaz.xacml.admin.view.fields.DesignatorSelectorField; |
| import org.apache.openaz.xacml.api.Identifier; |
| import org.apache.openaz.xacml.api.XACML3; |
| import com.vaadin.addon.jpacontainer.EntityItem; |
| import com.vaadin.addon.jpacontainer.fieldfactory.SingleSelectConverter; |
| import com.vaadin.data.Property.ValueChangeEvent; |
| import com.vaadin.data.Property.ValueChangeListener; |
| import com.vaadin.data.fieldgroup.FieldGroup; |
| import com.vaadin.data.fieldgroup.FieldGroup.CommitException; |
| import com.vaadin.data.fieldgroup.PropertyId; |
| import com.vaadin.data.util.filter.Compare; |
| import com.vaadin.data.util.filter.Not; |
| import com.vaadin.event.ShortcutAction.KeyCode; |
| import com.vaadin.shared.ui.combobox.FilteringMode; |
| import com.vaadin.ui.AbstractSelect.ItemCaptionMode; |
| import com.vaadin.ui.Alignment; |
| import com.vaadin.ui.Button; |
| import com.vaadin.ui.Button.ClickEvent; |
| import com.vaadin.ui.Button.ClickListener; |
| import com.vaadin.ui.ComboBox; |
| import com.vaadin.ui.FormLayout; |
| import com.vaadin.ui.TextArea; |
| import com.vaadin.ui.TextField; |
| import com.vaadin.ui.UI; |
| import com.vaadin.ui.Window; |
| |
| public class AttributeEditorWindow extends Window { |
| private static final long serialVersionUID = 1L; |
| private static final Log logger = LogFactory.getLog(AttributeEditorWindow.class); |
| private AttributeEditorWindow self = this; |
| |
| private boolean isSaved = false; |
| private Attribute attribute; |
| |
| private FormLayout mainLayout = new FormLayout(); |
| |
| @PropertyId("isDesignator") |
| DesignatorSelectorField selectDesignator; |
| |
| @PropertyId("selectorPath") |
| TextField selectorPath = new TextField("Attribute Selector Path"); |
| |
| @PropertyId("xacmlId") |
| TextField xacmlID = new TextField("XACML ID"); |
| |
| @PropertyId("categoryBean") |
| ComboBox category = new ComboBox("Category"); |
| |
| @PropertyId("description") |
| TextArea descriptionField = new TextArea("Description"); |
| |
| @PropertyId("datatypeBean") |
| ComboBox datatype = new ComboBox("DataType"); |
| |
| @PropertyId("constraintType") |
| ComboBox constraintTypes = new ComboBox("Constraint Type"); |
| |
| @PropertyId("constraintValues") |
| ConstraintField constraintValues; |
| |
| Button saveButton = new Button("Save"); |
| |
| FieldGroup fieldGroup = null; |
| |
| /** |
| * The constructor should first build the main layout, set the |
| * composition root and then do any custom initialization. |
| * |
| * The constructor will not be automatically regenerated by the |
| * visual editor. |
| */ |
| public AttributeEditorWindow(EntityItem<Attribute> entityItem) { |
| // |
| // Save our attribute |
| // |
| this.attribute = entityItem.getEntity(); |
| if (logger.isDebugEnabled()) { |
| logger.debug("Editing attribute: " + entityItem.getEntity().toString()); |
| } |
| // |
| // Set our shortcuts |
| // |
| this.setCloseShortcut(KeyCode.ESCAPE); |
| // |
| // Create our main layout |
| // |
| this.setContent(mainLayout); |
| // |
| // Finish setting up the main layout |
| // |
| this.mainLayout.setSpacing(true); |
| this.mainLayout.setMargin(true); |
| // |
| // Setup option group, binding the |
| // field group doesn't seem to work. |
| // |
| this.selectDesignator = new DesignatorSelectorField(entityItem); |
| this.selectDesignator.setCaption("Select the Attribute Type"); |
| this.selectDesignator.addValueChangeListener(new ValueChangeListener() { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| public void valueChange(ValueChangeEvent event) { |
| Object value = self.selectDesignator.getValue(); |
| if (value == null || ! (value instanceof Character)) { |
| self.selectorPath.setVisible(false); |
| } |
| if (((Character) value) == '1') { |
| self.selectorPath.setVisible(false); |
| } else { |
| self.selectorPath.setVisible(true); |
| } |
| } |
| }); |
| // |
| // Setup selector path |
| // |
| this.selectorPath.setImmediate(true); |
| this.selectorPath.setNullRepresentation(""); |
| this.selectorPath.setWidth("100%"); |
| // |
| // Setup the Category combo |
| // |
| this.category.setContainerDataSource(((XacmlAdminUI) UI.getCurrent()).getCategories()); |
| this.category.setItemCaptionMode(ItemCaptionMode.PROPERTY); |
| this.category.setItemCaptionPropertyId("xacmlId"); |
| this.category.setFilteringMode(FilteringMode.CONTAINS); |
| this.category.setImmediate(true); |
| this.category.setNullSelectionAllowed(false); |
| this.category.setConverter(new SingleSelectConverter<Object>(this.category)); |
| // |
| // Setup the Datatype combo |
| // |
| this.datatype.setContainerDataSource(((XacmlAdminUI) UI.getCurrent()).getDatatypes()); |
| this.datatype.setItemCaptionMode(ItemCaptionMode.PROPERTY); |
| this.datatype.setItemCaptionPropertyId("xacmlId"); |
| this.datatype.setFilteringMode(FilteringMode.CONTAINS); |
| this.datatype.setImmediate(true); |
| this.datatype.setNullSelectionAllowed(false); |
| this.datatype.setConverter(new SingleSelectConverter<Object>(this.datatype)); |
| // |
| // Setup the constraint type combo |
| // |
| this.constraintTypes.setContainerDataSource(((XacmlAdminUI) UI.getCurrent()).getConstraintTypes()); |
| this.constraintTypes.setItemCaptionMode(ItemCaptionMode.PROPERTY); |
| this.constraintTypes.setItemCaptionPropertyId("constraintType"); |
| this.constraintTypes.setFilteringMode(FilteringMode.CONTAINS); |
| this.constraintTypes.setImmediate(true); |
| this.constraintTypes.setNullSelectionAllowed(true); |
| this.constraintTypes.setConverter(new SingleSelectConverter<Object>(this.constraintTypes)); |
| // |
| // Setup the constraint value custom field |
| // |
| this.constraintValues = new ConstraintField(entityItem); |
| // |
| // Finish laying out the main layout |
| // |
| this.mainLayout.addComponent(this.selectDesignator); |
| this.mainLayout.addComponent(this.selectorPath); |
| this.mainLayout.addComponent(this.xacmlID); |
| this.mainLayout.addComponent(this.category); |
| this.mainLayout.addComponent(this.descriptionField); |
| this.mainLayout.addComponent(this.datatype); |
| this.mainLayout.addComponent(this.constraintTypes); |
| this.mainLayout.addComponent(this.constraintValues); |
| // |
| // Now create our field group and bind our bean items |
| // This will populate the components with the attribute's |
| // current value. |
| // |
| this.fieldGroup = new FieldGroup(entityItem); |
| this.fieldGroup.bindMemberFields(this); |
| // |
| // Finishing setting up after the bind. There are some components |
| // where initializing the bind causes some properties to be reset. |
| // |
| this.xacmlID.setWidth("100%"); |
| this.descriptionField.setNullRepresentation(""); |
| this.descriptionField.setWidth("100%"); |
| this.setupDatatype(this.attribute.getDatatypeBean().getIdentifer()); |
| this.datatype.addValueChangeListener(new ValueChangeListener() { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| public void valueChange(ValueChangeEvent event) { |
| Identifier id = self.getCurrentDatatype(); |
| if (id != null) { |
| self.setupDatatype(id); |
| } |
| } |
| }); |
| // |
| // Listen to when constraint type changes |
| // |
| this.constraintTypes.addValueChangeListener(new ValueChangeListener() { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| public void valueChange(ValueChangeEvent event) { |
| Object value = self.constraintTypes.getValue(); |
| if (value == null) { |
| self.constraintValues.resetContent(null, self.getCurrentDatatype()); |
| } else { |
| ConstraintType newValue = ((XacmlAdminUI) UI.getCurrent()).getConstraintTypes().getItem(value).getEntity(); |
| self.constraintValues.resetContent(newValue, self.getCurrentDatatype()); |
| } |
| } |
| }); |
| // |
| // Setup our "SAVE" button to commit the fields |
| // |
| this.mainLayout.addComponent(this.saveButton); |
| this.mainLayout.setComponentAlignment(this.saveButton, Alignment.MIDDLE_CENTER); |
| this.saveButton.addClickListener(new ClickListener() { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| public void buttonClick(ClickEvent event) { |
| try { |
| // |
| // SAVE the latest values |
| // |
| fieldGroup.commit(); |
| // |
| // Set that we did save the attribute |
| // |
| self.isSaved = true; |
| // |
| // Close the window |
| // |
| self.close(); |
| } catch (CommitException e) { |
| logger.error("Failed to commit fields", e); |
| } |
| } |
| |
| }); |
| // |
| // Add our close listener so we can discard anything that was changed. |
| // |
| this.addCloseListener(new CloseListener() { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| public void windowClose(CloseEvent e) { |
| if (self.isSaved == false) { |
| logger.info("discarding"); |
| // |
| // Discard any changes to the existing JPA container entity |
| // |
| self.fieldGroup.discard(); |
| // |
| // Make sure there are no filters on the container |
| // |
| ((XacmlAdminUI) UI.getCurrent()).getConstraintTypes().removeAllContainerFilters(); |
| } |
| } |
| |
| }); |
| // |
| // Set focus |
| // |
| this.xacmlID.focus(); |
| } |
| |
| private void setupDatatype(Identifier datatype) { |
| if (datatype.equals(XACML3.ID_DATATYPE_INTEGER) || |
| datatype.equals(XACML3.ID_DATATYPE_DOUBLE)) { |
| ((XacmlAdminUI) UI.getCurrent()).getConstraintTypes().removeAllContainerFilters(); |
| this.constraintTypes.setEnabled(true); |
| this.constraintValues.resetDatatype(datatype); |
| return; |
| } |
| if (datatype.equals(XACML3.ID_DATATYPE_STRING)) { |
| ((XacmlAdminUI) UI.getCurrent()).getConstraintTypes().addContainerFilter(new Not(new Compare.Equal("constraintType", ConstraintType.RANGE_TYPE))); |
| if (this.attribute.getConstraintType() != null && |
| this.attribute.getConstraintType().getConstraintType() != null && |
| this.attribute.getConstraintType().getConstraintType().equals(ConstraintType.RANGE_TYPE)) { |
| this.attribute.setConstraintType(null); |
| } |
| this.constraintValues.resetDatatype(datatype); |
| return; |
| } |
| // |
| // No constraint for all other datatypes |
| // |
| this.attribute.setConstraintType(null); |
| this.constraintTypes.select(null); |
| this.constraintTypes.setEnabled(false); |
| } |
| |
| private Identifier getCurrentDatatype() { |
| Object id = self.datatype.getValue(); |
| if (id != null) { |
| EntityItem<Datatype> dt = ((XacmlAdminUI) UI.getCurrent()).getDatatypes().getItem(id); |
| if (dt != null) { |
| return dt.getEntity().getIdentifer(); |
| } |
| } |
| return null; |
| } |
| |
| public boolean isSaved() { |
| return this.isSaved; |
| } |
| } |