components/visual-panels/usermgr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthRightsPanel.java
branchs11-update
changeset 2805 4888f6212f94
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/visual-panels/usermgr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthRightsPanel.java	Wed Oct 30 16:53:48 2013 -0400
@@ -0,0 +1,631 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panels.usermgr.client.swing;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.tree.*;
+import javax.swing.border.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/**
+ * SMC code adapted for Visual Panels
+ *
+ * Rights Profiles Panel for Rights Settings
+ */
+public class AuthRightsPanel extends JPanel {
+
+
+    public static Arranger profPanel;
+    private static DblTreeNode srcRoot;
+    private static DblTreeNode dstRoot;
+    private DefaultTreeModel srcModel, dstModel;
+
+    private DblTreeNode [] profNodes;
+    private ProfTreeNode [] profTreeNodes;
+
+    private ProfTreeNode currProfTreeNode;
+    private DblTreeNode currDblTreeNode;
+
+    private String targetRightName;
+    private String targetRight;
+    private JPanel securityPanel;
+
+    private UserManagedObject userObj = null;
+    private UserMgrPanelDescriptor panelDesc = null;
+
+    private Vector vAllRightObjs = null;
+
+    private boolean isProfListOK = true;
+
+    /**
+     * Constructs a panel to contain supplementary rights properties for
+     * the right object.
+     */
+    public AuthRightsPanel(UserMgrPanelDescriptor panelDesc,
+        UserManagedObject userObj) {
+
+	super();
+	this.panelDesc = panelDesc;
+	this.userObj = userObj;
+
+	createGui();
+	loadProfiles();
+    } // constructor
+
+
+    /**
+     * Method for creating GUI
+     */
+    private void createGui() {
+
+	// Set the panel layout
+	GridBagConstraints gbc = new GridBagConstraints();
+	this.setLayout(new GridBagLayout());
+
+	// Excluded and Included rights panel
+   	securityPanel = null;
+
+	profPanel = new Arranger("usermgr.advanced.auth_rights.available",
+		"usermgr.advanced.auth_rights.granted");
+
+	Dimension dimension = new Dimension(200, 300);
+	profPanel.srcTree.setCellRenderer(new ProfileRenderer(this));
+	profPanel.srcTree.setVisibleRowCount(10);
+	profPanel.srcTree.setSize(dimension);
+
+	profPanel.dstTree.setCellRenderer(new ProfileRenderer(this));
+	profPanel.dstTree.setVisibleRowCount(10);
+	profPanel.dstTree.setSize(dimension);
+
+	Constraints.constrain(this, profPanel,
+		0, 0, 1, 1,
+		gbc.BOTH, gbc.CENTER,
+		1.0, 1.0, 10, 10, 10, 10);
+
+    } // end createGui
+
+
+    /**
+     * Load the Source and Destination trees for rights excluded and
+     * included lists.
+     */
+    private void loadProfiles() {
+
+	// Reset the data models. So old data is discarded
+	profPanel.resetModels();
+
+
+	// Initialize the excluded rights list with all profiles
+	// except for the current one, since a profile can not be
+	// assigned to itself. Note that all profiles are created
+	// as top-level profiles.
+
+	vAllRightObjs = getAvailableProfs();
+
+	srcModel = (DefaultTreeModel) profPanel.srcTree.getModel();
+	srcRoot = (DblTreeNode) srcModel.getRoot();
+
+	dstModel = (DefaultTreeModel) profPanel.dstTree.getModel();
+	dstRoot = (DblTreeNode) dstModel.getRoot();
+
+	profNodes = new DblTreeNode[vAllRightObjs.size()];
+	profTreeNodes = new ProfTreeNode[vAllRightObjs.size()];
+
+	int n = 0;
+	Enumeration e = vAllRightObjs.elements();
+
+	// Build an array of tree nodes that can be used for sorting.
+
+	while (e.hasMoreElements()) {
+	    String rightObj = (String)e.nextElement();
+	    String rightName = rightObj;
+
+	    profTreeNodes[n] = new ProfTreeNode(rightObj);
+
+	    n++;
+	}
+
+	// Sort the list of ProfTreeNode objects.
+
+	if (profTreeNodes.length > 1) {
+	    NodeCompare comp = new NodeCompare();
+	    Sort.sort(profTreeNodes, comp);
+	}
+
+	// With the sorted tree nodes, now we build the src tree.
+	for (int i = 0; i < profTreeNodes.length; i++) {
+	    profNodes[i] = new DblTreeNode((Object)profTreeNodes[i]);
+
+	    srcModel.insertNodeInto(profNodes[i], srcRoot, i);
+	    TreePath nodepath = new TreePath(profNodes[i].getPath());
+	    // Make initial display of excluded list
+	    profPanel.srcTree.scrollPathToVisible(nodepath);
+	}
+
+
+	// Set TreeModel listeners
+	srcModel.addTreeModelListener(new TreeModelListener() {
+
+	    public void treeNodesInserted(TreeModelEvent e) {
+		enableProfileChoices(e);
+	    }
+
+	    public void treeNodesRemoved(TreeModelEvent e) {
+		disableProfileChoices(e);
+	    }
+
+	    public void treeNodesChanged(TreeModelEvent e) {}
+
+	    public void treeStructureChanged(TreeModelEvent e) {}
+
+	});
+
+	dstModel.addTreeModelListener(new TreeModelListener() {
+
+	    public void treeNodesInserted(TreeModelEvent e) {
+		updateDstTree(e);
+	    }
+
+	    public void treeNodesRemoved(TreeModelEvent e) {
+		updateDstTree(e);
+	    }
+
+	    public void treeNodesChanged(TreeModelEvent e) {}
+
+	    public void treeStructureChanged(TreeModelEvent e) {}
+
+	});
+
+	// Build subprofiles recursively
+	for (int i = 0; i < profNodes.length; i++) {
+	    rebuildSubProfiles(profNodes[i], profNodes[i]);
+	}
+
+	String [] subProfList = null;
+
+	// Get the list of profiles that are assigned to current user/role
+	// (in user_attr entry).
+	String rights = userObj.getAuthRights();
+	if (rights != null) {
+	    subProfList = userObj.getAuthRights().split(",");
+	}
+
+	profPanel.setInitSelection();
+	if (rights == null || subProfList == null) {
+	    return;
+	}
+
+	// Move subprofiles of current profile from excluded list
+	// to included list.
+	// Note that a dimmed profile will stay dimmed after the move.
+	// Therefore, a user can not "unassign" a dimmed profile on the
+	// included list.
+
+
+	for (int j = 0; j < subProfList.length; j++) {
+	    boolean foundSubProf = false;
+
+	    int count = 0;
+	    for (int i = 0; i < profNodes.length; i++) {
+		String profString = profNodes[i].toString();
+
+		if (profString.equals(subProfList[j])) {
+		    foundSubProf = true;
+		    count = i;
+		    break;
+		}
+
+	    }
+
+	    if (foundSubProf) {
+		profPanel.initLeaf(profPanel.srcTree,
+		    profPanel.dstTree, profNodes[count]);
+	    }
+	}
+
+	profPanel.setInitSelection();
+
+    } // end loadProfiles
+
+
+    private void updateDstTree(TreeModelEvent e) {
+
+	Vector<DblTreeNode> inclProfsVec = new Vector<DblTreeNode>();
+	Enumeration inclProfsEnum = dstRoot.breadthFirstEnumeration();
+
+	while (inclProfsEnum.hasMoreElements()) {
+	    DblTreeNode node = (DblTreeNode)inclProfsEnum.nextElement();
+	    inclProfsVec.addElement(node);
+	    node.setConflict(false);
+	}
+
+	// Maintain included names as array as optimization
+
+	DblTreeNode [] inclProfs = new DblTreeNode[inclProfsVec.size()];
+	inclProfsVec.copyInto(inclProfs);
+
+	if (inclProfs.length < 2)
+	    return;
+
+	for (int i = 0; i < inclProfs.length; i++) {
+	    String testString = inclProfs[i].toString();
+
+	    for (int j = i + 1; j < inclProfs.length; j++) {
+		if (testString.equals(inclProfs[j].toString())) {
+		    inclProfs[j].setConflict(true);
+		    inclProfs[i].setConflict(true);
+		    TreeNode [] nodes = inclProfs[j].getPath();
+		    DblTreeNode parentProf = (DblTreeNode)nodes[1];
+		    parentProf.setConflict(true);
+		}
+	    }
+	}
+
+    } // end updateDstTree
+
+
+    private void enableProfileChoices(TreeModelEvent e) {
+
+	// Get names of currently included profiles
+	if (e.getPath().length > 1)
+	    return;
+
+	Vector<String> inclProfsVec = new Vector<String>();
+	Enumeration inclProfs = dstRoot.depthFirstEnumeration();
+
+	while (inclProfs.hasMoreElements()) {
+	    inclProfsVec.addElement(inclProfs.nextElement().toString());
+	}
+
+	// Maintain included names as array as optimization
+
+	String [] inclProfNames = new String[inclProfsVec.size()];
+	inclProfsVec.copyInto(inclProfNames);
+
+	// Look for excluded list items needing updating
+
+	Enumeration topProfs = srcRoot.children();
+	while (topProfs.hasMoreElements()) {
+	    DblTreeNode nextTop = (DblTreeNode)topProfs.nextElement();
+	    boolean matchFound = false;
+	    Enumeration exclProfs = nextTop.depthFirstEnumeration();
+
+	    while (exclProfs.hasMoreElements()) {
+		String testString = exclProfs.nextElement().toString();
+		for (int i = 0; i < inclProfNames.length; i++) {
+		    if (testString.equals(inclProfNames[i])) {
+			matchFound = true;
+			break;
+		    }
+		}
+		if (matchFound)
+		    break;
+	    }
+
+	    // A Profile hierarchy needs to be enabled
+
+	    if (!matchFound) {
+		exclProfs = nextTop.depthFirstEnumeration();
+		while (exclProfs.hasMoreElements()) {
+		    DblTreeNode onNode =
+			(DblTreeNode) exclProfs.nextElement();
+		    onNode.setConflict(false);
+		}
+		nextTop.setConflict(false);
+	    }
+	}
+
+    } // end enableProfileChoices
+
+
+    private void disableProfileChoices(TreeModelEvent e) {
+
+	if (e.getPath().length > 1)
+	    return;
+
+	Object[] children = e.getChildren();
+	DblTreeNode node = (DblTreeNode)children[0];
+	Enumeration kids = node.breadthFirstEnumeration();
+	while (kids.hasMoreElements()) {
+	    disableRecursively((DblTreeNode)kids.nextElement());
+	}
+
+    } // end disableProfileChoices
+
+
+    private void disableRecursively(DblTreeNode node) {
+
+	String testString = node.toString();
+	Enumeration exclProfs = srcRoot.breadthFirstEnumeration();
+	while (exclProfs.hasMoreElements()) {
+	    DblTreeNode exclNode = (DblTreeNode)exclProfs.nextElement();
+	    if (testString.equals(exclNode.toString())) {
+		TreeNode [] nodes = exclNode.getPath();
+
+		DblTreeNode parentProf = (DblTreeNode)nodes[1];
+		if (!parentProf.isConflict()) {
+		    parentProf.setConflict(true);
+		    exclNode.setConflict(true);
+    		}
+	    }
+	}
+
+    } // end disableRecursively
+
+
+    private void rebuildSubProfiles(DblTreeNode profNode, DblTreeNode topNode) {
+
+	// First unlink the old children
+	int childCount = profNode.getChildCount();
+	for (int i = 0; i < childCount; i++) {
+	    DblTreeNode child = (DblTreeNode) srcModel.getChild(profNode, 0);
+	    srcModel.removeNodeFromParent(child);
+	}
+
+	// Then recursively construct new nodes for all the children
+	DblTreeNode childNode;
+	int i = 0;
+	Enumeration topList = topNode.breadthFirstEnumeration();
+
+	// Find sub-profile list in RightObj of cached tree node
+	ProfTreeNode pTreeNode = (ProfTreeNode)profNode.getUserObject();
+	String rObj = pTreeNode.getRightObj();
+	// ProfAttrObj targetProfAttr = rObj.getProfAttr();
+
+	String [] profList = null; // targetProfAttr.getProfNames();
+
+	if (profList == null)
+	    return;
+
+	for (int k = 0; k < profList.length; k++) {
+	    String name = profList[k];
+
+	    // Prevent infinite recursive loops
+	    boolean cyclic = false;
+	    while (topList.hasMoreElements()) {
+		if (name.equals(topList.nextElement().toString())) {
+		    cyclic = true;
+		    // Mark the parent as cyclic
+		    topNode.setCyclic(true);
+		    Enumeration dupNodes = topNode.breadthFirstEnumeration();
+		    while (dupNodes.hasMoreElements()) {
+			childNode = (DblTreeNode)dupNodes.nextElement();
+			if (name.equals(childNode.toString())) {
+			    childNode.setCyclic(true);
+			}
+		    }
+		    break;
+		}
+	    }
+
+	    for (int j = 0; j < profTreeNodes.length; j++) {
+		if (name.equals(profTreeNodes[j].toString())) {
+		    childNode = new DblTreeNode((Object)profTreeNodes[j]);
+
+		    srcModel.insertNodeInto(childNode, profNode, i++);
+		    childNode.setEnabled(false);
+		    if (cyclic)
+			childNode.setCyclic(true);
+		    else
+			rebuildSubProfiles(childNode, topNode);
+		}
+	    }
+	}
+
+    } // end rebuildSubProfiles
+
+
+    public String updateRightSubProps(String rightObj) {
+
+	if (isProfListOK) {
+	    Vector<String> vAssignedProfs = new Vector<String>();
+
+	    // Get the first generation children that are assigned to
+	    // current profile.
+	    DblTreeNode root = (DblTreeNode)dstModel.getRoot();
+	    Enumeration kids;
+	    kids = root.children();
+
+	    while (kids.hasMoreElements()) {
+		DblTreeNode childNode;
+		childNode = (DblTreeNode)kids.nextElement();
+		vAssignedProfs.addElement(childNode.toString());
+	    }
+
+	    // ProfAttrObj profAttr = rightObj.getProfAttr();
+	    // profAttr.setProfNamesVector(vAssignedProfs);
+	}
+	return (rightObj);
+
+    } // end updateRightSubProps
+
+    public Vector<String> getAssignedProfs() {
+	Vector<String> vAssignedProfs = new Vector<String>();
+
+	if (!isProfListOK) {
+	    return vAssignedProfs;
+	}
+
+	// Get the first generation children that are assigned to
+	// current profile.
+	DblTreeNode root = (DblTreeNode)dstModel.getRoot();
+	Enumeration kids;
+	kids = root.children();
+	while (kids.hasMoreElements()) {
+	    DblTreeNode childNode;
+	    childNode = (DblTreeNode)kids.nextElement();
+	    vAssignedProfs.addElement(childNode.toString());
+	}
+
+	return vAssignedProfs;
+    }
+
+    private Vector<String> getAvailableProfs() {
+        Vector<String> rights = new Vector<String>();
+	for (String s : panelDesc.getProfiles()) {
+	    rights.add(s);
+
+	}
+    	return (rights);
+    }
+
+    public void setUser(UserManagedObject userObj) {
+    	this.userObj = userObj;
+	loadProfiles();
+    }
+
+    public UserManagedObject updateUser() {
+        Vector<String> vProfs = getAssignedProfs();
+	String profStr;
+
+	if (vProfs.size() > 0) {
+		profStr = vProfs.elementAt(0);
+	} else {
+		profStr = "";
+	}
+
+	for (int i = 1; i < vProfs.size(); i++) {
+	    profStr = profStr.concat(",");
+	    profStr = profStr.concat(vProfs.elementAt(i));
+        }
+
+	userObj.getAuthRightsProperty().setValue(profStr);
+
+	return (userObj);
+    }
+
+
+
+class ProfileRenderer extends DefaultTreeCellRenderer {
+
+    private boolean selected;
+    Icon warningIcon;
+    AuthRightsPanel rightsPanel;
+
+    public ProfileRenderer(AuthRightsPanel rightsPanel) {
+
+	this.rightsPanel = rightsPanel;
+	setClosedIcon(null);
+	setOpenIcon(null);
+	setLeafIcon(null);
+    	warningIcon = Finder.getIcon("images/warning.gif");
+
+    }
+
+
+    public Component getTreeCellRendererComponent(
+	JTree tree,
+	Object value,
+	boolean selected,
+	boolean expanded,
+	boolean leaf,
+	int row,
+	boolean hasFocus) {
+
+	FocusEvent e = null;
+
+	this.selected = selected;
+
+	DefaultTreeCellRenderer cr =
+	    (DefaultTreeCellRenderer)tree.getCellRenderer();
+	cr.setLeafIcon(null);
+	DblTreeNode node = (DblTreeNode)value;
+
+	if (node.getParent() == null) {
+	    // maybe the same as row == 0
+	    setText(node.toString());
+
+	} else if (node.getUserObject() instanceof ProfTreeNode) {
+	    ProfTreeNode profsdef = (ProfTreeNode)node.getUserObject();
+	    setText(profsdef.toString());
+	    // setIcon(actionIcon);
+
+	    if (node.isConflict())
+		if (tree == rightsPanel.profPanel.dstTree)
+		    cr.setLeafIcon(warningIcon);
+	}
+
+	super.getTreeCellRendererComponent(tree, value, selected, expanded,
+	    leaf, row, hasFocus);
+
+	return this;
+
+    } // end getTreeCellRendererComponent
+
+}
+
+class ProfTreeNode {
+
+    String name;
+    String rightObj = null;
+
+    public ProfTreeNode(String rightObj) {
+	this.rightObj = rightObj;
+	this.name = rightObj;
+    }
+
+    public String getRightObj() {
+	return rightObj;
+    }
+
+    public String toString() {
+	return name;
+    }
+
+}
+
+class NodeCompare implements Compare {
+
+    /**
+     * The compare method compares two ProfTreeNode objects by comparing
+     * their profile names.  The parameters are specified as Object class
+     * objects for QuickSort.
+     *
+     * @param   a	The first Node.
+     * @param   b	The second Node.
+     *
+     */
+    public final int doCompare(Object a, Object b) {
+
+	ProfTreeNode e1, e2;
+	String e1Name, e2Name;
+
+	e1 = (ProfTreeNode)a;
+	e2 = (ProfTreeNode)b;
+	e1Name = e1.toString();
+	e2Name = e2.toString();
+	return (e1Name.compareTo(e2Name));
+
+    }
+
+}
+}