org.apache.openaz.xacml.admin.components.PolicyEditor.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.openaz.xacml.admin.components.PolicyEditor.java

Source

/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */

package org.apache.openaz.xacml.admin.components;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;

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.model.GitRepositoryContainer;
import org.apache.openaz.xacml.admin.model.PolicyContainer;
import org.apache.openaz.xacml.admin.util.AdminNotification;
import org.apache.openaz.xacml.admin.util.JPAUtils;
import org.apache.openaz.xacml.admin.view.windows.AttributeSelectionWindow;
import org.apache.openaz.xacml.admin.view.windows.AttributeValueEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.ExpressionBuilderComponent;
import org.apache.openaz.xacml.admin.view.windows.MatchEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.ObligationAdviceEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.PolicyEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.PolicySetEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.RuleEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.VariableDefinitionEditorWindow;
import org.apache.openaz.xacml.util.XACMLObjectCopy;
import org.apache.openaz.xacml.util.XACMLPolicyWriter;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Container.ItemSetChangeEvent;
import com.vaadin.data.Container.ItemSetChangeListener;
import com.vaadin.data.Item;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.DataBoundTransferable;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.event.ShortcutAction;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.server.BrowserWindowOpener;
import com.vaadin.server.FileDownloader;
import com.vaadin.server.StreamResource;
import com.vaadin.shared.ui.dd.VerticalDropLocation;
import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TabSheet.Tab;
import com.vaadin.ui.Table.TableDragMode;
import com.vaadin.ui.TreeTable;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window.CloseEvent;
import com.vaadin.ui.Window.CloseListener;

public class PolicyEditor extends CustomComponent {
    /*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

    @AutoGenerated
    private VerticalLayout mainLayout;

    @AutoGenerated
    private TreeTable tree;

    @AutoGenerated
    private HorizontalLayout horizontalLayoutToolbar;

    @AutoGenerated
    private Button buttonExport;

    @AutoGenerated
    private Button buttonViewXML;

    @AutoGenerated
    private Button buttonSave;

    @AutoGenerated
    private CheckBox checkBoxAutoSave;

    @AutoGenerated
    private CheckBox checkBoxReadOnly;

    private static final long serialVersionUID = 1L;
    private static Log logger = LogFactory.getLog(PolicyEditor.class);
    private final PolicyEditor self = this;

    private static final Action CREATE_POLICY = new Action("New Policy");
    private static final Action CREATE_POLICYSET = new Action("New Policy Set");
    private static final Action CREATE_RULE = new Action("New Rule");
    private static final Action EDIT_POLICY = new Action("Edit Policy");
    private static final Action EDIT_POLICYSET = new Action("Edit Policy Set");
    private static final Action EDIT_RULE = new Action("Edit Rule");
    private static final Action DELETE_POLICYSET = new Action("Delete Policy Set");
    private static final Action DELETE_POLICY = new Action("Delete Policy");
    private static final Action DELETE_RULE = new Action("Delete Rule");
    private static final Action CREATE_NEWANYOF = new Action("New Any Of (Match)");
    private static final Action CREATE_NEWALLOF = new Action("New All Of (Match)");
    private static final Action CREATE_NEWMATCH = new Action("New Match");
    private static final Action DELETE_ANYOF = new Action("Delete Any Of");
    private static final Action DELETE_ALLOF = new Action("Delete All Of");
    private static final Action DELETE_MATCH = new Action("Delete Match");
    private static final Action EDIT_MATCH = new Action("Edit Match");
    private static final Action EDIT_OBLIGATIONS = new Action("Edit Obligations");
    private static final Action DELETE_OBLIGATIONS = new Action("Delete Obligations");
    private static final Action EDIT_ADVICE = new Action("Edit Advice");
    private static final Action DELETE_ADVICE = new Action("Delete Advice");
    private static final Action CREATE_VARIABLE = new Action("Create Variable");
    private static final Action EDIT_VARIABLE = new Action("Edit Variable");
    private static final Action DELETE_VARIABLE = new Action("Delete Variable");
    private static final Action CREATE_TARGET = new Action("Create Target");
    private static final Action CREATE_CONDITION = new Action("Create Condition");
    private static final Action EDIT_CONDITION = new Action("Edit Condition");
    private static final Action DELETE_CONDITION = new Action("Delete Condition");
    private static final Action EDIT_EXPRESSIONS = new Action("Edit Expressions");

    private static final Action CLIPBOARD_CUT = new ShortcutAction("Cut", ShortcutAction.KeyCode.S,
            new int[] { ShortcutAction.ModifierKey.CTRL });
    private static final Action CLIPBOARD_COPY = new ShortcutAction("Copy", ShortcutAction.KeyCode.C,
            new int[] { ShortcutAction.ModifierKey.CTRL });
    private static final Action CLIPBOARD_PASTE = new ShortcutAction("Paste", ShortcutAction.KeyCode.V,
            new int[] { ShortcutAction.ModifierKey.CTRL });

    private static final Object[] VISIBLE_COLUMNS = new Object[] { PolicyContainer.PROPERTY_NAME,
            PolicyContainer.PROPERTY_SHORTALGORITHM, PolicyContainer.PROPERTY_DESCRIPTION };
    private static final String[] COLUMN_HEADERS = new String[] { "Name", "Algorithm or Effect", "Description" };

    private final File file;
    private final GitRepositoryContainer gitContainer;
    private final PolicyContainer policyContainer;
    private Tab tab = null;
    private boolean isModified = false;

    private Object clipboardObject = 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.
     * @throws IOException 
     */
    public PolicyEditor(File policyFile, GitRepositoryContainer gitContainer, boolean readOnly) throws IOException {
        buildMainLayout();
        setCompositionRoot(mainLayout);
        this.mainLayout.setSizeFull();
        //
        // Save
        //
        this.file = policyFile;
        this.gitContainer = gitContainer;
        this.policyContainer = new PolicyContainer(this.file);
        //
        // Its our data also
        //
        this.setData(policyFile);
        //
        // Initialize GUI
        //
        this.initializeCheckboxes(readOnly);
        this.initializeButtons();
        this.initializeDownload();
        this.initializeTree();
        // PLD TODO next release      this.initializeContextMenu();
        //
        // setup the caption etc.
        //
        this.setupCaption();
        this.resetComponents();
    }

    protected void initializeCheckboxes(boolean readOnly) {
        //
        // The readonly check box
        //
        this.checkBoxReadOnly.setImmediate(true);
        this.checkBoxReadOnly.setValue(readOnly);
        this.checkBoxReadOnly.addValueChangeListener(new ValueChangeListener() {
            private static final long serialVersionUID = 1L;

            @Override
            public void valueChange(ValueChangeEvent event) {
                self.resetComponents();
                self.setupCaption();
            }

        });
        //
        // The autosave check box
        //
        this.checkBoxAutoSave.setImmediate(true);
        this.checkBoxAutoSave.setValue(true);
    }

    protected void initializeButtons() {
        //
        // The Save button
        //
        this.buttonSave.addClickListener(new ClickListener() {
            private static final long serialVersionUID = 1L;

            @Override
            public void buttonClick(ClickEvent event) {
                self.savePolicy();
            }
        });
        //
        // Attach a window opener to the View XML button
        //
        BrowserWindowOpener opener = new BrowserWindowOpener(new StreamResource(new StreamResource.StreamSource() {
            private static final long serialVersionUID = 1L;

            @Override
            public InputStream getStream() {
                try {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Setting view xml button to: " + self.file.getAbsolutePath());
                    }
                    return new FileInputStream(self.file);
                } catch (Exception e) {
                    logger.error("Failed to open input stream " + self.file);
                }
                return null;
            }
        }, self.file.getName()));
        opener.setWindowName("_new");
        opener.extend(this.buttonViewXML);
    }

    protected void initializeDownload() {
        //
        // Create a stream resource pointing to the file
        //
        StreamResource r = new StreamResource(new StreamResource.StreamSource() {
            private static final long serialVersionUID = 1L;

            @Override
            public InputStream getStream() {
                try {
                    return new FileInputStream(self.file);
                } catch (Exception e) {
                    logger.error("Failed to open input stream " + self.file);
                }
                return null;
            }
        }, self.file.getName());
        r.setCacheTime(-1);
        r.setMIMEType("application/xml");
        //
        // Extend a downloader to attach to the Export Button
        //
        FileDownloader downloader = new FileDownloader(r);
        downloader.extend(this.buttonExport);
    }

    public void setTab(Tab tab) {
        this.tab = tab;
        this.setupCaption();
    }

    public boolean isAutoSave() {
        if (this.checkBoxAutoSave.isEnabled() == false) {
            return false;
        }
        return this.checkBoxAutoSave.getValue();
    }

    public boolean isReadOnly() {
        return this.checkBoxReadOnly.getValue();
    }

    protected void initializeTree() {
        //
        // Create our container and set it as the tree's data source
        //
        this.tree.setContainerDataSource(this.policyContainer);
        this.tree.setItemIconPropertyId("Icon");
        this.tree.setVisibleColumns(VISIBLE_COLUMNS);
        this.tree.setColumnHeaders(COLUMN_HEADERS);
        this.tree.setSelectable(true);
        this.tree.setSizeFull();
        //
        // Expand it down a few items
        //
        for (Object id : this.tree.getItemIds()) {
            this.tree.setCollapsed(id, false);
            for (Object child : this.tree.getChildren(id)) {
                this.tree.setCollapsed(child, false);
            }
        }
        //
        // Respond to double-click's
        //
        this.tree.addItemClickListener(new ItemClickListener() {
            private static final long serialVersionUID = 1L;

            @Override
            public void itemClick(ItemClickEvent event) {
                if (event.isDoubleClick()) {
                    if (self.isReadOnly()) {
                        AdminNotification.info("You are in read-only mode.");
                        return;
                    }
                    Object target = event.getItemId();
                    if (target instanceof PolicySetType) {
                        self.editPolicySet((PolicySetType) target,
                                (PolicySetType) self.policyContainer.getParent(target));
                    } else if (target instanceof PolicyType) {
                        self.editPolicy((PolicyType) target,
                                (PolicySetType) self.policyContainer.getParent(target));
                    } else if (target instanceof RuleType) {
                        self.editRule((RuleType) target, (PolicyType) self.policyContainer.getParent(target));
                    } else if (target instanceof ConditionType) {
                        self.editCondition((ConditionType) target,
                                (RuleType) self.policyContainer.getParent(target));
                    } else if (target instanceof VariableDefinitionType) {
                        self.editVariable((VariableDefinitionType) target,
                                (PolicyType) self.policyContainer.getParent(target));
                    } else if (target instanceof MatchType) {
                        self.editMatch((MatchType) target, (AllOfType) self.policyContainer.getParent(target), null,
                                null, "Edit Match");
                    } else if (target instanceof ObligationExpressionType) {
                        self.editObAdvice(true, self.policyContainer.getParent(target));
                    } else if (target instanceof AdviceExpressionType) {
                        self.editObAdvice(false, self.policyContainer.getParent(target));
                    }
                }
            }

        });
        //
        // Respond to container changes
        //
        this.policyContainer.addItemSetChangeListener(new ItemSetChangeListener() {
            private static final long serialVersionUID = 1L;

            @Override
            public void containerItemSetChange(ItemSetChangeEvent event) {
                self.isModified = true;
                if (self.isAutoSave()) {
                    self.savePolicy();
                } else {
                    self.setupCaption();
                    self.buttonSave.setEnabled(true);
                }
            }
        });
        //
        // Implement drag-n-drop
        //
        this.tree.setDropHandler(new DropHandler() {
            private static final long serialVersionUID = 1L;

            @Override
            public void drop(DragAndDropEvent event) {
                DataBoundTransferable t = (DataBoundTransferable) event.getTransferable();
                AbstractSelectTargetDetails target = (AbstractSelectTargetDetails) event.getTargetDetails();

                //
                // Get ids of the dragged item and the target item
                //
                Object sourceItemId = t.getData("itemId");
                Object targetItemId = target.getItemIdOver();
                VerticalDropLocation location = target.getDropLocation();
                if (logger.isDebugEnabled()) {
                    logger.debug("Drop " + sourceItemId + " target " + targetItemId + " location " + location);
                }
                //
                // Tell our container what to do
                //
                try {
                    if (location == VerticalDropLocation.MIDDLE) {
                        //
                        // Drop right on top of item making it a child
                        //
                        self.policyContainer.setParent(sourceItemId, targetItemId);
                    }

                    /*
                    } else if (location == VerticalDropLocation.TOP) {
                       //
                       // Drop at the top of the tree making it the previous
                       //
                       Object parent = self.policyContainer.getParent(targetItemId);
                       self.policyContainer.setParent(sourceItemId, parent);
                       self.policyContainer.moveAfterSibling(sourceItemId, targetItemId);
                       self.policyContainer.moveAfterSibling(targetItemId, sourceItemId);
                    } else if (location == VerticalDropLocation.BOTTOM) {
                       //
                       // Drop below another item
                       //
                       Object parent = self.policyContainer.getParent(targetItemId);
                       self.policyContainer.setParent(sourceItemId, targetItemId);
                       self.policyContainer.moveAfterSibling(sourceItemId, targetItemId);
                    }
                    */
                } catch (UnsupportedOperationException e) {
                    logger.error("Unsupported " + e.getLocalizedMessage());
                }
            }

            @Override
            public AcceptCriterion getAcceptCriterion() {
                return AcceptAll.get();
            }
        });
    }

    protected void removeObject(Object target) {
        if (target instanceof PolicySetType) {
            this.removePolicySet((PolicySetType) target);
        } else if (target instanceof PolicyType) {
            this.removePolicy((PolicyType) target);
        } else if (target instanceof RuleType) {
            this.removeRule((RuleType) target);
        } else if (target instanceof ConditionType) {
            this.removeCondition((ConditionType) target);
        } else if (target instanceof VariableDefinitionType) {
            this.removeVariable((VariableDefinitionType) target);
        } else if (target instanceof AdviceExpressionType) {
            this.removeAdvice((AdviceExpressionType) target);
        } else if (target instanceof ObligationExpressionType) {
            this.removeObligations((ObligationExpressionType) target);
        }
    }

    protected void removeAdvice(AdviceExpressionType target) {
        if (this.tree.removeItem(target) == false) {
            logger.error("Failed to remove advice.");
        }
    }

    protected void removeVariable(VariableDefinitionType target) {
        if (this.tree.removeItem(target) == false) {
            logger.error("Failed to remove variable.");
        }
    }

    protected void removeCondition(ConditionType target) {
        if (this.tree.removeItem(target) == false) {
            logger.error("Failed to remove condition.");
        }
    }

    protected void removeObligations(ObligationExpressionType target) {
        if (this.tree.removeItem(target) == false) {
            logger.error("Failed to remove obligations.");
        }
    }

    protected void removeRule(RuleType target) {
        if (this.tree.removeItem(target) == false) {
            logger.error("Failed to remove rule.");
        }
    }

    protected void removePolicy(PolicyType target) {
        Object parent = this.tree.getParent(target);
        if (parent == null) {
            this.deleteRoot(target);
        } else {
            if (this.tree.removeItem(target) == false) {
                logger.error("Failed to remove policy.");
            }
        }
    }

    protected void removePolicySet(PolicySetType target) {
        Object parent = this.tree.getParent(target);
        if (parent == null) {
            this.deleteRoot(target);
        } else {
            if (this.tree.removeItem(target) == false) {
                logger.error("Failed to remove policy set.");
            }
        }
    }

    /*
    protected void initializeContextMenu() {
       ContextMenu menu = new ContextMenu();
       menu.setAsTableContextMenu(this.tree);
       menu.addContextMenuTableListener(new TableListener() {
        
     @Override
     public void onContextMenuOpenFromFooter(
           ContextMenuOpenedOnTableFooterEvent event) {
        // TODO Auto-generated method stub
            
     }
        
     @Override
     public void onContextMenuOpenFromHeader(
           ContextMenuOpenedOnTableHeaderEvent event) {
        // TODO Auto-generated method stub
            
     }
        
     @Override
     public void onContextMenuOpenFromRow(ContextMenuOpenedOnTableRowEvent event) {
        logger.info("context menu row");
     }
       });
       menu.addItem("test");
    }
    */

    protected void savePolicy() {
        if (this.isReadOnly()) {
            logger.warn("Should not call savePolicy when in read only mode.");
            return;
        }
        Collection<?> roots = this.policyContainer.rootItemIds();
        if (roots.size() > 1) {
            logger.warn("More than one root policy.");
        }
        //
        // There should only be one root
        // Save the policy to disk.
        //
        for (Object root : roots) {
            logger.info("Saving policy: " + this.file.getName());
            //
            // TODO - Bump the version?
            //
            if (root instanceof PolicySetType) {
                XACMLPolicyWriter.writePolicyFile(Paths.get(this.file.getAbsolutePath()), (PolicySetType) root);
            } else if (root instanceof PolicyType) {
                XACMLPolicyWriter.writePolicyFile(Paths.get(this.file.getAbsolutePath()), (PolicyType) root);
            }
            //
            // TODO ????
            //
            this.gitContainer.updateItem(this.file);
            break; // NOPMD
        }
        //
        // No longer modified
        //
        this.isModified = false;
        this.setupCaption();
        this.resetComponents();
    }

    protected void installTreeActionHandler() {
        //
        // Remove any existing action handlers
        //
        this.tree.removeAllActionHandlers();
        //
        // Are we read-only?
        //
        if (this.isReadOnly()) {
            //
            // Yes - no action handler's allowed
            //
            return;
        }
        //
        // Setup our action handlers
        //
        this.tree.addActionHandler(new Handler() {
            private static final long serialVersionUID = 1L;

            @Override
            public Action[] getActions(Object target, Object sender) {
                //
                // Are we read-only?
                //
                if (self.isReadOnly()) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Policy is read-only");
                    }
                    return null;
                }
                if (target == null) {
                    //
                    // Nothing is selected, they right-clicked empty space
                    //
                    if (logger.isDebugEnabled()) {
                        logger.debug("action tree target is null");
                    }
                    return null;
                }
                if (target instanceof PolicySetType) {
                    List<Action> actions = new ArrayList<Action>();
                    actions.add(EDIT_POLICYSET);
                    if (((PolicySetType) target).getTarget() == null) {
                        actions.add(CREATE_TARGET);
                    }
                    /*
                    actions.add(CLIPBOARD_CUT);
                    actions.add(CLIPBOARD_COPY);
                    actions.add(CLIPBOARD_PASTE);
                    */
                    actions.add(CREATE_POLICYSET);
                    actions.add(CREATE_POLICY);
                    actions.add(EDIT_OBLIGATIONS);
                    actions.add(EDIT_ADVICE);
                    actions.add(DELETE_POLICYSET);
                    return (Action[]) actions.toArray(new Action[0]);
                }
                if (target instanceof PolicyType) {
                    List<Action> actions = new ArrayList<Action>();
                    actions.add(EDIT_POLICY);
                    if (((PolicyType) target).getTarget() == null) {
                        actions.add(CREATE_TARGET);
                    }
                    /*
                    actions.add(CLIPBOARD_CUT);
                    actions.add(CLIPBOARD_COPY);
                    actions.add(CLIPBOARD_PASTE);
                    */
                    actions.add(CREATE_RULE);
                    actions.add(CREATE_VARIABLE);
                    actions.add(EDIT_OBLIGATIONS);
                    actions.add(EDIT_ADVICE);
                    actions.add(DELETE_POLICY);
                    return (Action[]) actions.toArray(new Action[0]);
                }
                if (target instanceof RuleType) {
                    List<Action> actions = new ArrayList<Action>();
                    actions.add(EDIT_RULE);
                    if (((RuleType) target).getTarget() == null) {
                        actions.add(CREATE_TARGET);
                    }
                    /*
                    actions.add(CLIPBOARD_CUT);
                    actions.add(CLIPBOARD_COPY);
                    actions.add(CLIPBOARD_PASTE);
                    */
                    if (((RuleType) target).getCondition() == null) {
                        actions.add(CREATE_CONDITION);
                    }
                    actions.add(EDIT_OBLIGATIONS);
                    actions.add(EDIT_ADVICE);
                    actions.add(DELETE_RULE);
                    return (Action[]) actions.toArray(new Action[0]);
                }
                if (target instanceof TargetType) {
                    return new Action[] { CREATE_NEWANYOF };
                }
                if (target instanceof AnyOfType) {
                    return new Action[] { CREATE_NEWALLOF, DELETE_ANYOF };
                }
                if (target instanceof AllOfType) {
                    return new Action[] { CREATE_NEWMATCH, DELETE_ALLOF };
                }
                if (target instanceof MatchType) {
                    return new Action[] { EDIT_MATCH, DELETE_MATCH };
                }
                if (target instanceof ConditionType) {
                    return new Action[] { EDIT_CONDITION, DELETE_CONDITION };
                }
                if (target instanceof VariableDefinitionType) {
                    return new Action[] { EDIT_VARIABLE, DELETE_VARIABLE };
                }
                if (target instanceof ObligationExpressionType) {
                    return new Action[] { EDIT_OBLIGATIONS, DELETE_OBLIGATIONS };
                }
                if (target instanceof AdviceExpressionType) {
                    return new Action[] { EDIT_ADVICE, DELETE_ADVICE };
                }
                return null;
            }

            @Override
            public void handleAction(Action action, Object sender, Object target) {
                if (action == CLIPBOARD_CUT) {
                    assert target != null;
                    self.clipboardObject = XACMLObjectCopy.deepCopy(target);
                    self.removeObject(target);
                    return;
                }
                if (action == CLIPBOARD_COPY) {
                    assert target != null;
                    self.clipboardObject = XACMLObjectCopy.deepCopy(target);
                    return;
                }
                if (action == CLIPBOARD_PASTE) {
                    assert target != null;
                    self.clipboardPaste(target, true);
                    return;
                }
                if (action == CREATE_POLICYSET) {
                    assert target instanceof PolicySetType;
                    self.editPolicySet(null, (PolicySetType) target);
                    return;
                }
                if (action == CREATE_POLICY) {
                    assert target instanceof PolicySetType;
                    self.editPolicy(null, (PolicySetType) target);
                    return;
                }
                if (action == CREATE_RULE) {
                    assert target instanceof PolicyType;
                    self.editRule(null, (PolicyType) target);
                    return;
                }
                if (action == CREATE_TARGET) {
                    assert target instanceof RuleType || target instanceof PolicyType
                            || target instanceof PolicySetType;
                    TargetType newTarget = new TargetType();
                    self.policyContainer.addItem(newTarget, target);
                    return;
                }
                if (action == EDIT_POLICYSET) {
                    assert target instanceof PolicySetType;
                    self.editPolicySet((PolicySetType) target,
                            (PolicySetType) self.policyContainer.getParent(target));
                    return;
                }
                if (action == EDIT_POLICY) {
                    assert target instanceof PolicyType;
                    self.editPolicy((PolicyType) target, (PolicySetType) self.policyContainer.getParent(target));
                    return;
                }
                if (action == EDIT_RULE) {
                    assert target instanceof RuleType;
                    self.editRule((RuleType) target, (PolicyType) self.policyContainer.getParent(target));
                    return;
                }
                if (action == DELETE_POLICYSET) {
                    assert target instanceof PolicySetType;
                    self.removePolicySet((PolicySetType) target);
                    return;
                }
                if (action == DELETE_POLICY) {
                    assert target instanceof PolicyType;
                    self.removePolicy((PolicyType) target);
                    return;
                }
                if (action == DELETE_RULE) {
                    assert target instanceof RuleType;
                    self.removeRule((RuleType) target);
                    return;
                }
                if (action == CREATE_NEWANYOF) {
                    assert target instanceof TargetType;
                    self.editMatch(null, null, null, (TargetType) target, "Create New Match");
                    return;
                }
                if (action == CREATE_NEWALLOF) {
                    assert target instanceof AnyOfType;
                    self.editMatch(null, null, (AnyOfType) target, null, "Create New Match");
                    return;
                }
                if (action == CREATE_NEWMATCH) {
                    if (target instanceof AllOfType) {
                        self.editMatch(null, (AllOfType) target, null, null, "Create New Match");
                    } else if (target instanceof TargetType) {
                        self.editMatch(null, null, null, (TargetType) target, "Create New Match");
                    } else {
                        assert false;
                    }
                    return;
                }
                if (action == DELETE_ANYOF) {
                    assert target instanceof AnyOfType;
                    self.removeAnyOf((AnyOfType) target, (TargetType) self.policyContainer.getParent(target));
                    return;
                }
                if (action == DELETE_ALLOF) {
                    assert target instanceof AllOfType;
                    self.removeAllOf((AllOfType) target, (AnyOfType) self.policyContainer.getParent(target));
                    return;
                }
                if (action == DELETE_MATCH) {
                    assert target instanceof MatchType;
                    self.removeMatch((MatchType) target, (AllOfType) self.policyContainer.getParent(target));
                    return;
                }
                if (action == EDIT_MATCH) {
                    assert target instanceof MatchType;
                    self.editMatch((MatchType) target, (AllOfType) self.policyContainer.getParent(target), null,
                            null, "Edit Match");
                    return;
                }
                if (action == EDIT_OBLIGATIONS) {
                    assert target instanceof RuleType || target instanceof PolicyType
                            || target instanceof PolicySetType || target instanceof ObligationExpressionType;
                    if (target instanceof ObligationExpressionType) {
                        self.editObAdvice(true, self.policyContainer.getParent(target));
                    } else {
                        self.editObAdvice(true, target);
                    }
                    return;
                }
                if (action == DELETE_OBLIGATIONS) {
                    assert target instanceof ObligationExpressionType;
                    self.removeObligations((ObligationExpressionType) target);
                    return;
                }
                if (action == EDIT_ADVICE) {
                    assert target instanceof RuleType || target instanceof PolicyType
                            || target instanceof PolicySetType || target instanceof AdviceExpressionType;
                    if (target instanceof AdviceExpressionType) {
                        self.editObAdvice(false, self.policyContainer.getParent(target));
                    } else {
                        self.editObAdvice(false, target);
                    }
                    return;
                }
                if (action == DELETE_ADVICE) {
                    assert target instanceof AdviceExpressionType;
                    self.removeAdvice((AdviceExpressionType) target);
                    return;
                }
                if (action == CREATE_VARIABLE) {
                    assert target instanceof PolicyType;
                    self.editVariable(null, (PolicyType) target);
                    return;
                }
                if (action == CREATE_CONDITION) {
                    assert target instanceof RuleType;
                    self.editCondition(null, (RuleType) target);
                    return;
                }
                if (action == EDIT_CONDITION) {
                    assert target instanceof ConditionType;
                    self.editCondition((ConditionType) target, (RuleType) self.policyContainer.getParent(target));
                    return;
                }
                if (action == DELETE_CONDITION) {
                    assert target instanceof ConditionType;
                    self.removeCondition((ConditionType) target);
                    return;
                }
                if (action == EDIT_EXPRESSIONS) {
                    return;
                }
                if (action == DELETE_VARIABLE) {
                    assert target instanceof VariableDefinitionType;
                    self.removeVariable((VariableDefinitionType) target);
                    return;
                }
                if (action == EDIT_VARIABLE) {
                    assert target instanceof VariableDefinitionType;
                    self.editVariable((VariableDefinitionType) target,
                            (PolicyType) self.policyContainer.getParent(target));
                    return;
                }
            }
        });
    }

    protected void resetComponents() {
        if (this.isReadOnly()) {
            this.checkBoxAutoSave.setEnabled(false);
            this.buttonSave.setEnabled(false);
            this.tree.setDragMode(TableDragMode.NONE);
            this.tree.removeAllActionHandlers();
            this.tree.setReadOnly(true);
        } else {
            this.checkBoxAutoSave.setEnabled(true);
            this.buttonSave.setEnabled(this.isModified);
            this.tree.setReadOnly(false);
            this.tree.setDragMode(TableDragMode.ROW);
            this.installTreeActionHandler();
        }
    }

    public void setupCaption() {
        String caption = this.file.getName();
        if (this.isModified) {
            caption = caption + " *";
        }
        if (this.isReadOnly()) {
            caption = caption + " (Read-Only)";
        }
        if (this.tab != null) {
            this.tab.setCaption(caption);
        }
    }

    protected void editPolicySet(final PolicySetType policy, final PolicySetType parent) {
        logger.info("editPolicySet: " + policy + " parent " + parent);
        //
        // Create a copy
        //
        final PolicySetType newPolicySet = (policy == null ? new PolicySetType() : XACMLObjectCopy.copy(policy));
        //
        // Create window
        //
        final PolicySetEditorWindow window = new PolicySetEditorWindow(newPolicySet);
        window.setCaption(policy == null ? "Create New Policy Set" : "Edit Policy Set");
        window.setModal(true);
        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) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("user did NOT save");
                    }
                    return;
                }
                //
                // Was it a new Policy Set?
                //
                if (policy == null) {
                    logger.info("adding new policy set " + newPolicySet.getPolicySetId());
                    //
                    // Yes - new add it in
                    //
                    if (newPolicySet.getTarget() == null) {
                        newPolicySet.setTarget(new TargetType());
                    }
                    if (self.policyContainer.addItem(newPolicySet, parent) == null) {
                        logger.error("Failed to add new policy set");
                    } else {
                        self.tree.setCollapsed(parent, false);
                        self.tree.setCollapsed(newPolicySet, false);
                        self.tree.select(newPolicySet);
                    }
                } else {
                    logger.info("updating new policy set " + newPolicySet.getPolicySetId());
                    //
                    // No - copy everything
                    //
                    policy.setDescription(newPolicySet.getDescription());
                    policy.setVersion(newPolicySet.getVersion());
                    policy.setPolicyCombiningAlgId(newPolicySet.getPolicyCombiningAlgId());
                    //
                    // Update
                    //
                    self.policyContainer.updateItem(policy);
                }
            }
        });
        window.center();
        UI.getCurrent().addWindow(window);
    }

    protected void editPolicy(final PolicyType policy, final PolicySetType parent) {
        //
        // Create a copy
        //
        final PolicyType newPolicy = (policy == null ? new PolicyType() : XACMLObjectCopy.copy(policy));
        //
        // Create window
        //
        final PolicyEditorWindow window = new PolicyEditorWindow(newPolicy);
        window.setCaption(policy == null ? "Create New Policy" : "Edit Policy");
        window.setModal(true);
        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;
                }
                //
                // Was it a new Policy?
                //
                if (policy == null) {
                    //
                    // Yes - new add it in
                    //
                    if (newPolicy.getTarget() == null) {
                        newPolicy.setTarget(new TargetType());
                    }
                    if (self.policyContainer.addItem(newPolicy, parent) == null) {
                        logger.error("Failed to add policy");
                    } else {
                        self.tree.setCollapsed(parent, false);
                        self.tree.setCollapsed(newPolicy, false);
                        self.tree.select(newPolicy);
                    }
                } else {
                    //
                    // No - copy everything
                    //
                    policy.setDescription(newPolicy.getDescription());
                    policy.setVersion(newPolicy.getVersion());
                    policy.setRuleCombiningAlgId(newPolicy.getRuleCombiningAlgId());
                    //
                    // Update
                    //
                    self.policyContainer.updateItem(policy);
                }
            }
        });
        window.center();
        UI.getCurrent().addWindow(window);
    }

    protected void editRule(final RuleType rule, final PolicyType parent) {
        //
        // Create a copy
        //
        final RuleType newRule = (rule == null ? new RuleType() : XACMLObjectCopy.copy(rule));
        //
        // Create window
        //
        final RuleEditorWindow window = new RuleEditorWindow(newRule);
        window.setCaption(rule == null ? "Create New Rule" : "Edit Rule");
        window.setModal(true);
        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;
                }
                //
                // Was this a new rule?
                //
                if (rule == null) {
                    //
                    // Yes a new rule
                    //
                    if (newRule.getTarget() == null) {
                        newRule.setTarget(new TargetType());
                    }
                    if (self.policyContainer.addItem(newRule, parent) == null) {
                        logger.error("Failed to add new rule");
                    } else {
                        self.tree.setCollapsed(parent, false);
                        self.tree.setCollapsed(newRule, false);
                        self.tree.select(newRule);
                    }
                } else {
                    //
                    // No - editing existing rule. Copy everything
                    //
                    rule.setEffect(newRule.getEffect());
                    rule.setDescription(newRule.getDescription());
                    self.policyContainer.updateItem(rule);
                }
            }
        });
        window.center();
        UI.getCurrent().addWindow(window);
    }

    protected void editCondition(final ConditionType condition, final RuleType rule) {
        //
        // Make a copy of it first, in case the user manipulates it
        // and then decides to NOT save it
        //
        final ConditionType copyCondition = (condition == null ? new ConditionType()
                : XACMLObjectCopy.copy(condition));
        //
        // Create the window
        //
        final ExpressionBuilderComponent expression = new ExpressionBuilderComponent(copyCondition,
                (copyCondition.getExpression() != null ? copyCondition.getExpression().getValue() : null), null,
                self.policyContainer.getVariables());
        if (condition == null) {
            expression.setCaption("Create An Expression For The Condition");
        } else {
            expression.setCaption("Edit The Condition Expression");
        }
        expression.setModal(true);
        //
        // Add the close listener
        //
        expression.addCloseListener(new CloseListener() {
            private static final long serialVersionUID = 1L;

            @Override
            public void windowClose(CloseEvent e) {
                //
                // Did the user hit save?
                //
                if (expression.isSaved() == false) {
                    return;
                }
                //
                // Were we creating something new?
                //
                if (condition == null) {
                    //
                    // Yes add the new one into the container
                    //
                    if (self.policyContainer.addItem(copyCondition, rule) == null) {
                        logger.error("Failed to add condition");
                    } else {
                        self.tree.setCollapsed(rule, false);
                        self.tree.setCollapsed(copyCondition, false);
                        self.tree.select(copyCondition);
                    }
                } else {
                    //
                    // We were editing an existing condition, so copy
                    // over the new edited expression.
                    //
                    condition.setExpression(copyCondition.getExpression());
                    //
                    // Update the container
                    //
                    self.policyContainer.updateItem(condition);
                }
            }
        });
        expression.center();
        UI.getCurrent().addWindow(expression);
    }

    protected void editVariable(final VariableDefinitionType variable, final PolicyType parent) {
        //
        // Make a copy of it first, in case the user manipulates it
        // and then decides to NOT save it
        //
        final VariableDefinitionType copyVariable = (variable == null ? new VariableDefinitionType()
                : XACMLObjectCopy.copy(variable));
        //
        // Have the user create or edit the Variables ID
        //
        final VariableDefinitionEditorWindow editor = new VariableDefinitionEditorWindow(copyVariable);
        if (variable == null) {
            editor.setCaption("Create Variable");
        } else {
            editor.setCaption(
                    "Edit Variable" + (copyVariable.getVariableId() == null ? "" : copyVariable.getVariableId()));
        }
        editor.setModal(true);
        editor.addCloseListener(new CloseListener() {
            private static final long serialVersionUID = 1L;

            @Override
            public void windowClose(CloseEvent e) {
                //
                // Did the user click save button?
                //
                if (editor.isSaved() == false) {
                    return;
                }
                //
                // Create the window
                //
                final ExpressionBuilderComponent expression = new ExpressionBuilderComponent(copyVariable,
                        (copyVariable.getExpression() != null ? copyVariable.getExpression().getValue() : null),
                        null, self.policyContainer.getVariables());
                expression.setCaption("Edit The Variable \"" + copyVariable.getVariableId() + "\" Expression");
                //
                // Add the close listener
                //
                expression.addCloseListener(new CloseListener() {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public void windowClose(CloseEvent e) {
                        //
                        // Did the user click save button?
                        //
                        if (expression.isSaved() == false) {
                            return;
                        }
                        //
                        // Was it a new variable or were we editing an existing one?
                        //
                        if (variable == null) {
                            //
                            // New one, add it to the container
                            //
                            if (self.policyContainer.addItem(copyVariable, parent) == null) {
                                logger.error("Failed to add variable");
                            } else {
                                self.tree.setCollapsed(parent, false);
                                self.tree.setCollapsed(copyVariable, false);
                                self.tree.select(copyVariable);
                            }
                        } else {
                            //
                            // We were editing one, copy it back over.
                            //
                            variable.setVariableId(copyVariable.getVariableId());
                            variable.setExpression(copyVariable.getExpression());
                            //
                            // Update the container
                            //
                            self.policyContainer.updateItem(variable);
                        }
                    }
                });
                expression.center();
                UI.getCurrent().addWindow(expression);
            }
        });
        editor.center();
        UI.getCurrent().addWindow(editor);
    }

    protected void editMatch(final MatchType match, final AllOfType allOf, final AnyOfType anyOf,
            final TargetType target, final String caption) {
        //
        // Create an empty match or copy the one we are going to edit.
        //
        final MatchType newMatch = (match == null ? new MatchType() : XACMLObjectCopy.copy(match));
        //
        // Have user select an attribute
        //
        final AttributeSelectionWindow selection = new AttributeSelectionWindow(null,
                (newMatch.getAttributeDesignator() != null ? newMatch.getAttributeDesignator()
                        : newMatch.getAttributeSelector()));
        selection.setCaption("Select Attribute To Match Against");
        selection.setModal(true);
        selection.addCloseListener(new CloseListener() {
            private static final long serialVersionUID = 1L;

            @Override
            public void windowClose(CloseEvent event) {
                //
                // Did the user save anything?
                //
                if (selection.isSaved() == false) {
                    return;
                }
                //
                // Save the selected attribute
                //
                final Attribute attribute = selection.getAttribute();
                if (attribute.isDesignator()) {
                    newMatch.setAttributeDesignator(JPAUtils.createDesignator(attribute));
                } else {
                    newMatch.setAttributeSelector(JPAUtils.createSelector(attribute));
                }
                //
                // Yes - now match it up to a function
                //
                final MatchEditorWindow editor = new MatchEditorWindow(newMatch, attribute.getDatatypeBean());
                editor.setCaption(caption);
                editor.setModal(true);
                editor.addCloseListener(new CloseListener() {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public void windowClose(CloseEvent event) {
                        //
                        // Did the user hit save?
                        //
                        if (editor.isSaved() == false) {
                            return;
                        }
                        //
                        // Yes - now we need the value to check the attribute against
                        //
                        final AttributeValueType copyAttributeValue = (newMatch.getAttributeValue() == null
                                ? new AttributeValueType()
                                : newMatch.getAttributeValue());
                        //                  String currentValue = null;
                        //                  if (newMatch.getAttributeValue() != null) {
                        //                     currentValue = XACMLObjectCopy.getContent(newMatch.getAttributeValue().getContent());
                        //                  }
                        final AttributeValueEditorWindow value = new AttributeValueEditorWindow(copyAttributeValue,
                                attribute.getDatatypeBean());
                        value.setCaption("Set the value the attribute should match against.");
                        value.setModal(true);
                        value.addCloseListener(new CloseListener() {
                            private static final long serialVersionUID = 1L;

                            @Override
                            public void windowClose(CloseEvent event) {
                                //
                                // Did the user save?
                                //
                                if (value.isSaved() == false) {
                                    return;
                                }
                                //
                                // Yes - copy the value into the match
                                //
                                AttributeValueType val = new AttributeValueType();
                                val.getContent().add(value.getValue());
                                val.setDataType(value.getDatatype().getXacmlId());
                                newMatch.setAttributeValue(val);
                                //
                                // Was this a new match or were we editing an
                                // existing match?
                                //
                                if (match != null) {
                                    //
                                    // Editing - now we can save it
                                    //
                                    match.setAttributeDesignator(newMatch.getAttributeDesignator());
                                    match.setAttributeSelector(newMatch.getAttributeSelector());
                                    match.setAttributeValue(newMatch.getAttributeValue());
                                    match.setMatchId(newMatch.getMatchId());
                                    //
                                    // Update the container
                                    //
                                    self.policyContainer.updateItem(match);
                                } else {
                                    //
                                    // Do we have a parent(s)?
                                    //
                                    AllOfType allOfParent = allOf;
                                    AnyOfType anyOfParent = anyOf;
                                    if (allOfParent == null) {
                                        //
                                        // No direct AllOfParent
                                        //
                                        if (anyOfParent == null) {
                                            //
                                            // No AnyOfParent
                                            //
                                            if (target == null) {
                                                logger.error("We should NOT get this");
                                                return;
                                            }
                                            anyOfParent = new AnyOfType();
                                            if (self.policyContainer.addItem(anyOfParent, target) == null) {
                                                logger.error("Failed to add anyOf parent");
                                                assert false;
                                            }
                                            self.tree.setCollapsed(anyOfParent, false);
                                        }
                                        allOfParent = new AllOfType();
                                        if (self.policyContainer.addItem(allOfParent, anyOfParent) == null) {
                                            logger.error("Failed to add allOf parent");
                                            assert false;
                                        }
                                        self.tree.setCollapsed(allOfParent, false);
                                    }
                                    //
                                    // Add the MatchType into the Tree
                                    //
                                    if (self.policyContainer.addItem(newMatch, allOfParent) == null) {
                                        logger.error("Failed to add match");
                                        assert false;
                                    }
                                    self.tree.select(newMatch);
                                }
                            }
                        });
                        value.center();
                        UI.getCurrent().addWindow(value);
                    }
                });
                editor.center();
                UI.getCurrent().addWindow(editor);
            }
        });
        selection.center();
        UI.getCurrent().addWindow(selection);
    }

    protected void deleteRoot(Object root) {
        //
        // TODO - prompt user for new root object
        //

    }

    protected void editObAdvice(boolean isObligation, final Object target) {
        //
        // Get the object
        //
        String caption;
        Object expressionsObject = null;
        if (target instanceof RuleType) {
            if (isObligation) {
                expressionsObject = ((RuleType) target).getObligationExpressions();
                if (expressionsObject == null) {
                    caption = "Create New Obligation for Rule";
                } else {
                    caption = "Edit Obligations for Rule";
                }
            } else {
                expressionsObject = ((RuleType) target).getAdviceExpressions();
                if (expressionsObject == null) {
                    caption = "Create New Advice for Rule";
                } else {
                    caption = "Edit Advice for Rule";
                }
            }
        } else if (target instanceof PolicyType) {
            if (isObligation) {
                expressionsObject = ((PolicyType) target).getObligationExpressions();
                if (expressionsObject == null) {
                    caption = "Create New Obligation for Policy";
                } else {
                    caption = "Edit Obligations for Policy";
                }
            } else {
                expressionsObject = ((PolicyType) target).getAdviceExpressions();
                if (expressionsObject == null) {
                    caption = "Create New Advice for Policy";
                } else {
                    caption = "Edit Advice for Policy";
                }
            }
        } else if (target instanceof PolicySetType) {
            if (isObligation) {
                expressionsObject = ((PolicySetType) target).getObligationExpressions();
                if (expressionsObject == null) {
                    caption = "Create New Obligation for Policy Set";
                } else {
                    caption = "Edit Obligation for Policy Set";
                }
            } else {
                expressionsObject = ((PolicySetType) target).getAdviceExpressions();
                if (expressionsObject == null) {
                    caption = "Create New Advice for Policy Set";
                } else {
                    caption = "Edit Advice for Policy Set";
                }
            }
        } else {
            throw new IllegalArgumentException("Expected a rule/policy/policyset.");
        }
        //
        // Make a copy
        //
        final Object originalExpressions = expressionsObject;
        final Object copyExpression = (originalExpressions == null
                ? (isObligation ? new ObligationExpressionsType() : new AdviceExpressionsType())
                : originalExpressions instanceof ObligationExpressionsType
                        ? XACMLObjectCopy.copy((ObligationExpressionsType) originalExpressions)
                        : XACMLObjectCopy.copy((AdviceExpressionsType) originalExpressions));
        //
        // Invoke the editor window
        //
        final ObligationAdviceEditorWindow window = new ObligationAdviceEditorWindow(copyExpression,
                this.policyContainer.getVariables());
        window.setCaption(caption);
        window.setModal(true);
        window.addCloseListener(new CloseListener() {
            private static final long serialVersionUID = 1L;

            @Override
            public void windowClose(CloseEvent e) {
                //
                // Did the user save?
                //
                if (window.isSaved() == false) {
                    return;
                }
                //
                // It was saved - is this a new object?
                //
                if (originalExpressions == null) {
                    //
                    // New object
                    //
                    if (self.policyContainer.addItem(copyExpression, target) == null) {
                        logger.error("Failed to add expression");
                        assert false;
                    }
                } else {
                    //
                    // Editing an existing object.
                    //
                    if (originalExpressions instanceof ObligationExpressionsType) {
                        //
                        // Remove old obligations
                        //
                        while (((ObligationExpressionsType) originalExpressions).getObligationExpression()
                                .isEmpty() == false) {
                            //                  for (ObligationExpressionType old : ((ObligationExpressionsType) originalExpressions).getObligationExpression()) {
                            ObligationExpressionType old = ((ObligationExpressionsType) originalExpressions)
                                    .getObligationExpression().get(0);
                            self.policyContainer.removeItem(old);
                        }
                        //
                        // Copy new ones in
                        //
                        for (ObligationExpressionType newObligation : ((ObligationExpressionsType) copyExpression)
                                .getObligationExpression()) {
                            self.policyContainer.addItem(newObligation,
                                    (ObligationExpressionsType) originalExpressions);
                        }
                    } else if (originalExpressions instanceof AdviceExpressionsType) {
                        ((AdviceExpressionsType) originalExpressions).getAdviceExpression().clear();
                        ((AdviceExpressionsType) originalExpressions).getAdviceExpression()
                                .addAll(((AdviceExpressionsType) copyExpression).getAdviceExpression());
                    }
                }
            }
        });
        window.center();
        UI.getCurrent().addWindow(window);
    }

    protected void removeMatch(MatchType match, AllOfType parent) {
        assert match != null && parent != null;
        if (self.policyContainer.removeItem(match) == false) {
            logger.error("Failed to remove match");
            assert false;
        }
        //
        // Check for empty AllOf's
        //
        if (parent.getMatch().isEmpty()) {
            this.removeAllOf(parent, (AnyOfType) this.policyContainer.getParent(parent));
        }
    }

    protected void removeAllOf(AllOfType allOf, AnyOfType parent) {
        assert allOf != null && parent != null;
        if (self.policyContainer.removeItem(allOf) == false) {
            logger.error("Failed to remove AllOf");
            assert false;
        }
        //
        // Check for empty AnyOf's
        //
        if (parent.getAllOf().isEmpty()) {
            this.removeAnyOf(parent, (TargetType) this.policyContainer.getParent(parent));
        }
    }

    protected void removeAnyOf(AnyOfType anyOf, TargetType parent) {
        assert anyOf != null && parent != null;
        if (self.policyContainer.removeItem(anyOf) == false) {
            logger.error("Failed to remove anyOf");
            assert false;
        }
    }

    protected boolean clipboardPaste(final Object target, boolean performPaste) {
        if (this.clipboardObject == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("nothing in clipboard.");
            }
            return false;
        }
        boolean doPaste = false;
        if (this.clipboardObject instanceof PolicySetType && target instanceof PolicySetType) {
            doPaste = true;
        }
        if (this.clipboardObject instanceof PolicyType && target instanceof PolicySetType) {
            doPaste = true;
        }
        if (this.clipboardObject instanceof RuleType && target instanceof PolicyType) {
            doPaste = true;
        }
        if (doPaste == false) {
            //
            // Pasting clipboard object onto target not
            // possible.
            //
            return false;
        }
        if (performPaste == false) {
            //
            // They did not ask to do the actual paste,
            // but the called wanted to know if it was
            // possible.
            //
            return true;
        }
        //
        // Do the actual paste
        //
        Item item = this.policyContainer.addItem(XACMLObjectCopy.deepCopy(this.clipboardObject), target);
        assert item != null;
        this.tree.select(this.clipboardObject);

        return true;
    }

    @AutoGenerated
    private VerticalLayout buildMainLayout() {
        // common part: create layout
        mainLayout = new VerticalLayout();
        mainLayout.setImmediate(false);
        mainLayout.setWidth("-1px");
        mainLayout.setHeight("100.0%");
        mainLayout.setMargin(false);
        mainLayout.setSpacing(true);

        // top-level component properties
        setWidth("-1px");
        setHeight("100.0%");

        // horizontalLayoutToolbar
        horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
        mainLayout.addComponent(horizontalLayoutToolbar);
        mainLayout.setExpandRatio(horizontalLayoutToolbar, 1.0f);

        // tree
        tree = new TreeTable();
        tree.setImmediate(true);
        tree.setWidth("100.0%");
        tree.setHeight("100.0%");
        mainLayout.addComponent(tree);
        mainLayout.setExpandRatio(tree, 1.0f);

        return mainLayout;
    }

    @AutoGenerated
    private HorizontalLayout buildHorizontalLayoutToolbar() {
        // common part: create layout
        horizontalLayoutToolbar = new HorizontalLayout();
        horizontalLayoutToolbar.setImmediate(false);
        horizontalLayoutToolbar.setWidth("-1px");
        horizontalLayoutToolbar.setHeight("-1px");
        horizontalLayoutToolbar.setMargin(true);
        horizontalLayoutToolbar.setSpacing(true);

        // checkBoxReadOnly
        checkBoxReadOnly = new CheckBox();
        checkBoxReadOnly.setCaption("Read Only");
        checkBoxReadOnly.setImmediate(false);
        checkBoxReadOnly.setDescription("Check this to turn-off policy editing.");
        checkBoxReadOnly.setWidth("-1px");
        checkBoxReadOnly.setHeight("-1px");
        horizontalLayoutToolbar.addComponent(checkBoxReadOnly);

        // checkBoxAutoSave
        checkBoxAutoSave = new CheckBox();
        checkBoxAutoSave.setCaption("Auto Save");
        checkBoxAutoSave.setImmediate(false);
        checkBoxAutoSave.setDescription("Check this to turn-on automatic saving of policy when a change occurs.");
        checkBoxAutoSave.setWidth("-1px");
        checkBoxAutoSave.setHeight("-1px");
        horizontalLayoutToolbar.addComponent(checkBoxAutoSave);

        // buttonSave
        buttonSave = new Button();
        buttonSave.setCaption("Save");
        buttonSave.setImmediate(true);
        buttonSave.setDescription("Click to save the policy.");
        buttonSave.setWidth("-1px");
        buttonSave.setHeight("-1px");
        horizontalLayoutToolbar.addComponent(buttonSave);

        // buttonViewXML
        buttonViewXML = new Button();
        buttonViewXML.setCaption("View XML");
        buttonViewXML.setImmediate(true);
        buttonViewXML.setWidth("-1px");
        buttonViewXML.setHeight("-1px");
        horizontalLayoutToolbar.addComponent(buttonViewXML);

        // buttonExport
        buttonExport = new Button();
        buttonExport.setCaption("Export Policy");
        buttonExport.setImmediate(false);
        buttonExport.setWidth("-1px");
        buttonExport.setHeight("-1px");
        horizontalLayoutToolbar.addComponent(buttonExport);

        return horizontalLayoutToolbar;
    }
}