BrowseSchemaPanel.java revision 776a73e6a9d48721747ed06cf70746b661d3b03a
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* 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 legal-notices/CDDLv1_0.txt.
* 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 2008-2010 Sun Microsystems, Inc.
* Portions Copyright 2014-2015 ForgeRock AS
*/
/**
* The pane that is displayed when the user clicks on 'Browse Schema'.
*/
public class BrowseSchemaPanel extends StatusGenericPanel
{
private static final long serialVersionUID = -6462914563743569830L;
private FilterTextField filter;
private JButton applyButton;
private JButton newAttribute;
private JButton newObjectClass;
private JLabel lNumberOfElements;
private SchemaBrowserRightPanel entryPane;
private JScrollPane treeScroll;
private TreePath lastEntryTreePath;
private Schema lastSchema;
private GenericDialog newAttributeDialog;
private GenericDialog newObjectClassDialog;
private JMenuItem deleteMenuItem;
private JPopupMenu popup;
private CommonSchemaElements lastCreatedElement;
private final LocalizableMessage REQUIRED_ATTRIBUTES =
private final LocalizableMessage OPTIONAL_ATTRIBUTES =
private CategoryTreeNode attributes =
private CategoryTreeNode objectClasses =
private CategoryTreeNode standardObjectClasses =
new CategoryTreeNode(
private CategoryTreeNode standardAttributes =
new CategoryTreeNode(
private CategoryTreeNode configurationObjectClasses =
new CategoryTreeNode(
private CategoryTreeNode configurationAttributes =
new CategoryTreeNode(
private CategoryTreeNode customObjectClasses =
new CategoryTreeNode(
private CategoryTreeNode customAttributes =
new CategoryTreeNode(
private CategoryTreeNode matchingRules =
private CategoryTreeNode syntaxes =
new CategoryTreeNode(
private CategoryTreeNode[] underRootNodes =
{
};
private CategoryTreeNode[] categoryNodes = {
};
private JLabel lNoMatchFound;
private boolean ignoreSelectionEvents;
private LocalizableMessage NO_SCHEMA_ITEM_SELECTED =
private LocalizableMessage CATEGORY_ITEM_SELECTED =
private LocalizableMessage MULTIPLE_ITEMS_SELECTED =
/**
* Default constructor.
*
*/
public BrowseSchemaPanel()
{
super();
createLayout();
}
/** {@inheritDoc} */
public boolean requiresBorder()
{
return false;
}
/** {@inheritDoc} */
public boolean requiresScroll()
{
return false;
}
/** {@inheritDoc} */
public boolean callConfigurationChangedInBackground()
{
return true;
}
/** {@inheritDoc} */
public void toBeDisplayed(boolean visible)
{
if (w instanceof GenericDialog)
{
}
else if (w instanceof GenericFrame)
{
}
}
/**
* Creates the layout of the panel (but the contents are not populated here).
*/
private void createLayout()
{
newObjectClass.setOpaque(false);
{
/** {@inheritDoc} */
{
}
});
newAttribute.setOpaque(false);
{
/** {@inheritDoc} */
{
}
});
new DefaultComboBoxModel<>(new LocalizableMessage[]{
NAME,
TYPE,
filter = new FilterTextField();
{
/** {@inheritDoc} */
public void keyReleased(KeyEvent e)
{
&& applyButton.isEnabled())
{
}
}
});
{
/** {@inheritDoc} */
{
}
});
applyButton.setOpaque(false);
{
/** {@inheritDoc} */
{
}
});
// The button panel
}
private JPanel createButtonsPanel()
{
buttonsPanel.setOpaque(true);
closeButton.setOpaque(false);
{
/** {@inheritDoc} */
{
closeClicked();
}
});
return buttonsPanel;
}
/** {@inheritDoc} */
public LocalizableMessage getTitle()
{
return INFO_CTRL_PANEL_MANAGE_SCHEMA_TITLE.get();
}
/** {@inheritDoc} */
public Component getPreferredFocusComponent()
{
return filter;
}
/** {@inheritDoc} */
public void closeClicked()
{
super.closeClicked();
}
/** {@inheritDoc} */
public void okClicked()
{
// No ok button
}
/** {@inheritDoc} */
{
}
private Component createSplitPane()
{
lNoMatchFound.setVisible(false);
entryPane = new SchemaBrowserRightPanel();
{
/** {@inheritDoc} */
{
}
});
{
{
}
});
{
/** {@inheritDoc} */
{
if (!ignoreSelectionEvents)
{
ignoreSelectionEvents = true;
if (entryPane.mustCheckUnsavedChanges())
{
ignoreSelectionEvents = true;
switch (entryPane.checkUnsavedChanges())
{
case DO_NOT_SAVE:
break;
case SAVE:
break;
case CANCEL:
ignoreSelectionEvents = false;
return;
}
{
}
else
{
}
}
boolean deletableElementsSelected = false;
boolean nonDeletableElementsSelected = false;
{
{
if (node instanceof CategoryTreeNode)
{
nonDeletableElementsSelected = true;
}
else if (node instanceof CustomObjectClassTreeNode
|| node instanceof CustomAttributeTreeNode)
{
deletableElementsSelected = true;
}
else if (node instanceof SchemaElementTreeNode)
{
nonDeletableElementsSelected = true;
}
}
}
ignoreSelectionEvents = false;
}
}
});
{
}
tree.setRootVisible(false);
addPopupMenu();
return pane;
}
/** {@inheritDoc} */
{
}
/** {@inheritDoc} */
{
boolean schemaChanged;
{
}
{
schemaChanged = false;
}
else
{
}
if (schemaChanged)
{
lastSchema = schema;
{
public void run()
{
{
errorPane.setVisible(false);
}
}
});
}
else if (lastSchema == null)
{
{
errorPane.setVisible(true);
}
}
}
/**
* Selects the node in the tree that corresponds to a given schema element.
* @param root the node we must start searching for the node to be selected.
* @param element the schema element.
* @param model the tree model.
* @return <CODE>true</CODE> if the node was found and selected and
* <CODE>false</CODE> otherwise.
*/
{
boolean found = false;
for (int i=0; i<n && !found; i++)
{
if (node instanceof SchemaElementTreeNode)
{
{
found = true;
}
}
if (!found)
{
}
}
return found;
}
/**
* Repopulates the tree.
* @param tree the tree to be repopulated.
* @param forceScroll whether the scroll must be reset or not.
*/
{
if (lastSchema == null)
{
return;
}
ignoreSelectionEvents = true;
{
}
{
{
{
}
{
}
else
{
}
}
}
{
{
{
}
{
}
else
{
}
}
}
{
if (mustAdd(matchingRule))
{
}
}
{
{
{
}
}
}
int i = 0;
int positionUnderRoot = 0;
boolean expand = filterProvided;
{
}
else if (!expand)
{
}
if (expand)
{
}
{
}
else if (!expand)
{
}
if (expand)
{
}
int positionUnderAttributes = 0;
int positionUnderObjectClass = 0;
{
{
{
}
}
else
{
expand = false;
if (parent == standardObjectClasses
|| parent == customObjectClasses
|| parent == configurationObjectClasses)
{
{
}
else
{
}
}
else if (parent == standardAttributes
|| parent == customAttributes
|| parent == configurationAttributes)
{
{
}
else
{
}
}
else
{
{
}
else
{
}
}
{
if (newSelectionPath == null
{
if (lastCreatedElement != null)
{
if (node instanceof CustomObjectClassTreeNode
&& lastCreatedElement instanceof ObjectClass)
{
{
}
}
else if (node instanceof CustomAttributeTreeNode
&& lastCreatedElement instanceof AttributeType
{
}
}
{
}
}
}
if (expand || filterProvided)
{
}
}
i++;
}
{
{
}
}
if (newSelectionPath != null)
{
}
{
}
{
tree.expandPath(p);
}
ignoreSelectionEvents = false;
if (nElements > 0)
{
lNumberOfElements.setVisible(true);
}
else
{
lNumberOfElements.setVisible(false);
}
{
{
if (!(node instanceof CategoryTreeNode))
{
break;
}
}
}
repaint();
{
public void run()
{
if (forceScroll)
{
}
else
{
}
}
});
}
/**
* Updates the right entry panel.
*
*/
private void updateEntryPane()
{
{
}
{
if (node instanceof StandardObjectClassTreeNode)
{
}
else if (node instanceof ConfigurationObjectClassTreeNode)
{
}
else if (node instanceof CustomObjectClassTreeNode)
{
}
else if (node instanceof StandardAttributeTreeNode)
{
}
else if (node instanceof ConfigurationAttributeTreeNode)
{
}
else if (node instanceof CustomAttributeTreeNode)
{
}
else if (node instanceof MatchingRuleTreeNode)
{
}
else if (node instanceof AttributeSyntaxTreeNode)
{
}
else
{
}
}
else
{
{
boolean categorySelected = false;
int nNonCategory = 0;
{
if (node instanceof CategoryTreeNode)
{
categorySelected = true;
}
else
{
nNonCategory ++;
}
}
if (nNonCategory == 0)
{
}
else if (categorySelected)
{
}
else
{
}
}
else
{
}
}
}
/** Adds a popup menu. */
private void addPopupMenu()
{
popup = new JPopupMenu();
{
/** {@inheritDoc} */
{
}
});
{
/** {@inheritDoc} */
{
}
});
{
/** {@inheritDoc} */
{
}
});
deleteMenuItem.setEnabled(false);
}
private void deleteClicked()
{
{
{
if (node instanceof CustomObjectClassTreeNode)
{
}
else if (node instanceof CustomAttributeTreeNode)
{
}
}
}
{
}
{
if (orderedAttributes.isEmpty())
{
}
else if (orderedObjectClasses.isEmpty())
{
}
else
{
}
{
}
{
{
null,
dlg);
dlg.setVisible(true);
}
}
}
{
}
}
{
}
{
}
{
if (primaryName != null)
{
}
{
}
}
/**
* Check whether the provided attribute must be added or not.
* @param attr the attribute.
* @return <CODE>true</CODE> if the attribute must be added and
* <CODE>false</CODE> otherwise.
*/
{
if (f.length () > 0)
{
{
return mustAddAttributeName(attr, f);
}
{
}
else
{
return false;
}
}
return true;
}
{
}
{
{
{
return false;
}
}
return true;
}
/**
* Check whether the provided object class must be added or not.
* @param oc the objectclass.
* @return <CODE>true</CODE> if the objectclass must be added and
* <CODE>false</CODE> otherwise.
*/
{
if (f.length () > 0)
{
{
return mustAddObjectClassName(oc, f);
}
{
}
{
}
{
return mustAddAnyObjectClassName(oc, f);
}
{
return mustAddParentObjectClassName(oc, f);
}
else
{
return false;
}
}
return true;
}
{
{
{
return true;
}
}
return false;
}
{
{
}
else
{
}
return mustAddAttributeName(f, definedAttrs);
}
{
boolean mustAdd = true;
{
mustAdd = false;
{
if (mustAdd)
{
break;
}
}
if (!mustAdd)
{
break;
}
}
return mustAdd;
}
{
{
if (mustAddObjectClassName(parent, f) ||
{
return true;
}
}
return false;
}
/**
* Finds out if a class is descendant of another class using equality of
* pointers.
* @param ocParent the parent object class.
* @param oChild the (potentially) descendant object class.
* @return {@code true} if the class is a descendant of the parent class
* and {@code false} otherwise.
*/
{
{
for (ObjectClass o : superiors)
{
{
return true;
}
}
}
return false;
}
/**
* Check whether the provided matching rule must be added or not.
* @param matchingRule the matching rule.
* @return <CODE>true</CODE> if the matching rule must be added and
* <CODE>false</CODE> otherwise.
*/
{
if (f.length () > 0)
{
{
}
return false;
}
return true;
}
/**
* Check whether the provided attribute syntax must be added or not.
* @param syntax the attribute syntax.
* @return <CODE>true</CODE> if the attribute syntax must be added and
* <CODE>false</CODE> otherwise.
*/
{
if (f.length () > 0)
{
{
}
return false;
}
return true;
}
{
{
}
return matchFilter(values, f, false);
}
boolean exact)
{
{
boolean matchFilter = exact
if (matchFilter)
{
return true;
}
}
return false;
}
{
}
private void newAttributeClicked()
{
if (newAttributeDialog == null)
{
Utilities.getParentDialog(this));
Utilities.getParentDialog(this));
{
{
}
});
}
newAttributeDialog.setVisible(true);
}
private void newObjectClassClicked()
{
if (newObjectClassDialog == null)
{
Utilities.getParentDialog(this));
Utilities.getParentDialog(this));
{
{
}
});
}
newObjectClassDialog.setVisible(true);
}
{
if (o instanceof CommonSchemaElements)
{
}
}
{
"ds-folder.png",
"ds-folder.png", "ds-folder.png", "ds-folder.png", "ds-folder.png",
"ds-folder.png", "ds-rule-folder.png", "ds-syntax-folder.png"};
{
}
StandardAttributeTreeNode.class, CustomAttributeTreeNode.class,
StandardObjectClassTreeNode.class, CustomObjectClassTreeNode.class,
MatchingRuleTreeNode.class, AttributeSyntaxTreeNode.class};
"ds-class.png", "ds-class.png", "ds-class.png", "ds-rule.png",
"ds-syntax.png"};
{
}
}
/** Specific class used to render the nodes in the tree. It uses specific icons for the nodes. */
protected class SchemaTreeCellRenderer extends TreeCellRenderer
{
private static final long serialVersionUID = -3390568254259441766L;
/** {@inheritDoc} */
boolean hasFocus)
{
return this;
}
{
{
}
return icon;
}
}
{
// Reorder objectClasses and attributes to delete them in the proper order.
{
int index = -1;
{
{
index = i+1;
}
}
if (index == -1)
{
}
else
{
}
}
return new LinkedHashSet<>(lOrderedOcs);
}
{
{
int index = -1;
{
{
{
index = i+1;
}
else
{
}
}
}
if (index == -1)
{
}
else
{
}
}
return new LinkedHashSet<>(lOrderedAttributes);
}
private LocalizableMessage getConfirmationMessage(
{
// Analyze objectClasses
{
{
{
childClasses.add(o);
}
}
}
// Analyze attributes
{
{
{
}
}
{
{
}
{
}
}
{
}
}
if (!childClasses.isEmpty())
{
{
}
{
}
else
{
}
}
if (!childAttributes.isEmpty())
{
{
}
{
}
else
{
}
}
if (!dependentClasses.isEmpty())
{
{
}
else
{
}
}
{
}
{
}
}
}