/* * 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 * or http://forgerock.org/license/CDDLv1.0.html. * 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 */ package org.opends.guitools.controlpanel.ui; import static org.opends.messages.AdminToolMessages.*; import java.awt.Component; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.swing.DefaultListModel; import javax.swing.JLabel; import javax.swing.JList; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.ui.components.TitlePanel; import org.opends.guitools.controlpanel.util.LowerCaseComparator; import org.opends.guitools.controlpanel.util.Utilities; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.opends.server.types.AttributeType; import org.opends.server.types.CommonSchemaElements; import org.opends.server.types.ObjectClass; import org.opends.server.types.Schema; import static org.opends.server.types.CommonSchemaElements.*; /** * The panel that displays a standard object class definition. * */ public class StandardObjectClassPanel extends SchemaElementPanel { private static final long serialVersionUID = 5561268287795223026L; private TitlePanel titlePanel = new TitlePanel(LocalizableMessage.EMPTY, LocalizableMessage.EMPTY); private JLabel lParent; private JLabel name = Utilities.createDefaultLabel(); private JLabel parent = Utilities.createDefaultLabel(); private JLabel oid = Utilities.createDefaultLabel(); private JLabel origin = Utilities.createDefaultLabel(); private JLabel description = Utilities.createDefaultLabel(); private JLabel aliases = Utilities.createDefaultLabel(); private JLabel type = Utilities.createDefaultLabel(); private JList requiredAttributes = new JList(new DefaultListModel()); private JList optionalAttributes = new JList(new DefaultListModel()); private static LocalizableMessage ABSTRACT_VALUE = INFO_CTRL_PANEL_OBJECTCLASS_ABSTRACT_LABEL.get(); private static LocalizableMessage STRUCTURAL_VALUE = INFO_CTRL_PANEL_OBJECTCLASS_STRUCTURAL_LABEL.get(); private static LocalizableMessage AUXILIARY_VALUE = INFO_CTRL_PANEL_OBJECTCLASS_AUXILIARY_LABEL.get(); private static LocalizableMessage OBSOLETE_VALUE = INFO_CTRL_PANEL_OBJECTCLASS_OBSOLETE_LABEL.get(); private Map hmAttrs = new HashMap<>(); /** Default constructor of the panel. */ public StandardObjectClassPanel() { createLayout(); } /** {@inheritDoc} */ @Override public LocalizableMessage getTitle() { return INFO_CTRL_PANEL_STANDARD_OBJECTCLASS_TITLE.get(); } /** {@inheritDoc} */ @Override public Component getPreferredFocusComponent() { return requiredAttributes; } /** {@inheritDoc} */ @Override public void configurationChanged(ConfigurationChangeEvent ev) { } /** {@inheritDoc} */ @Override public void okClicked() { } /** * Creates the layout of the panel (but the contents are not populated here). */ protected void createLayout() { createBasicLayout(this, new GridBagConstraints()); setBorder(PANEL_BORDER); } /** * Creates the basic layout of the panel. * @param c the container where all the components will be layed out. * @param gbc the grid bag constraints. */ protected void createBasicLayout(Container c, GridBagConstraints gbc) { requiredAttributes.setVisibleRowCount(5); optionalAttributes.setVisibleRowCount(9); LocalizableMessage[] labels = { INFO_CTRL_PANEL_OBJECTCLASS_NAME_LABEL.get(), INFO_CTRL_PANEL_OBJECTCLASS_PARENT_LABEL.get(), INFO_CTRL_PANEL_OBJECTCLASS_OID_LABEL.get(), INFO_CTRL_PANEL_OBJECTCLASS_ALIASES_LABEL.get(), INFO_CTRL_PANEL_OBJECTCLASS_ORIGIN_LABEL.get(), INFO_CTRL_PANEL_OBJECTCLASS_DESCRIPTION_LABEL.get(), INFO_CTRL_PANEL_OBJECTCLASS_TYPE_LABEL.get() }; JLabel[] values = {name, parent, oid, aliases, origin, description, type}; gbc.gridy = 0; gbc.gridwidth = 2; addErrorPane(c, gbc); gbc.gridy ++; titlePanel.setTitle(INFO_CTRL_PANEL_OBJECTCLASS_DETAILS.get()); gbc.fill = GridBagConstraints.NONE; gbc.anchor = GridBagConstraints.WEST; gbc.insets.top = 5; gbc.insets.bottom = 7; c.add(titlePanel, gbc); gbc.insets.bottom = 0; gbc.insets.top = 8; gbc.gridy ++; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; for (int i=0; i < labels.length; i++) { gbc.insets.left = 0; gbc.gridx = 0; JLabel l = Utilities.createPrimaryLabel(labels[i]); if (i == 1) { lParent = l; } c.add(l, gbc); gbc.insets.left = 10; gbc.gridx = 1; c.add(values[i], gbc); gbc.gridy ++; } labels = new LocalizableMessage[] { INFO_CTRL_PANEL_REQUIRED_ATTRIBUTES_LABEL.get(), INFO_CTRL_PANEL_OPTIONAL_ATTRIBUTES_LABEL.get() }; JList[] lists = {requiredAttributes, optionalAttributes}; gbc.anchor = GridBagConstraints.NORTHWEST; for (int i=0; i<2; i++) { gbc.insets.left = 0; gbc.gridx = 0; JLabel l = Utilities.createPrimaryLabel(labels[i]); gbc.weightx = 0.0; gbc.fill = GridBagConstraints.HORIZONTAL; c.add(l, gbc); gbc.insets.left = 10; gbc.gridx = 1; if (i == 0) { gbc.weighty = 0.35; } else { gbc.weighty = 0.65; } gbc.weightx = 1.0; gbc.fill = GridBagConstraints.BOTH; gbc.insets.top = 10; c.add(Utilities.createScrollPane(lists[i]), gbc); gbc.gridy ++; gbc.weighty = 0.0; JLabel explanation = Utilities.createInlineHelpLabel( INFO_CTRL_PANEL_INHERITED_ATTRIBUTES_HELP.get()); gbc.insets.top = 3; c.add(explanation, gbc); gbc.gridy ++; final JList list = lists[i]; MouseAdapter clickListener = new MouseAdapter() { /** {@inheritDoc} */ @Override public void mouseClicked(MouseEvent ev) { if (ev.getClickCount() == 1) { attrSelected(list); } } }; list.addMouseListener(clickListener); KeyAdapter keyListener = new KeyAdapter() { /** {@inheritDoc} */ @Override public void keyTyped(KeyEvent ev) { if (ev.getKeyChar() == KeyEvent.VK_SPACE || ev.getKeyChar() == KeyEvent.VK_ENTER) { attrSelected(list); } } }; list.addKeyListener(keyListener); } } /** * Returns the message describing the schema element origin (file, RFC, etc.). * @param element the schema element. * @return the message describing the schema element origin (file, RFC, etc.). */ static LocalizableMessage getOrigin(CommonSchemaElements element) { LocalizableMessageBuilder returnValue = new LocalizableMessageBuilder(); String fileName = getSchemaFile(element); String xOrigin = Utilities.getOrigin(element); if (xOrigin != null) { returnValue.append(xOrigin); if (fileName != null) { returnValue.append(" -"); returnValue.append( INFO_CTRL_PANEL_DEFINED_IN_SCHEMA_FILE.get(fileName)); } } else if (fileName != null) { returnValue.append(INFO_CTRL_PANEL_DEFINED_IN_SCHEMA_FILE.get(fileName)); } else { returnValue.append(NOT_APPLICABLE); } return returnValue.toMessage(); } /** * Updates the contents of the panel with the provided object class. * @param oc the object class. * @param schema the schema. */ public void update(ObjectClass oc, Schema schema) { if (oc == null || schema == null) { // Ignore: this is called to get an initial panel size. return; } hmAttrs.clear(); String n = oc.getPrimaryName(); if (n == null) { n = NOT_APPLICABLE.toString(); } titlePanel.setDetails(LocalizableMessage.raw(n)); name.setText(n); parent.setText(getSuperiorText(oc)); oid.setText(oc.getOID()); origin.setText(getOrigin(oc).toString()); n = oc.getDescription(); if (n == null) { n = NOT_APPLICABLE.toString(); } description.setText(n); ArrayList otherNames = new ArrayList<>(); Iterable ocNames = oc.getNormalizedNames(); String primaryName = oc.getPrimaryName(); if (primaryName == null) { primaryName = ""; } for (String name : ocNames) { if (!name.equalsIgnoreCase(primaryName)) { otherNames.add(name); } } if (!otherNames.isEmpty()) { n = Utilities.getStringFromCollection(otherNames, ", "); } else { n = NOT_APPLICABLE.toString(); } aliases.setText(n); type.setText(getTypeValue(oc).toString()); Comparator lowerCaseComparator = new LowerCaseComparator(); SortedSet requiredAttrs = new TreeSet<>(lowerCaseComparator); Set inheritedAttrs = new HashSet<>(); for (AttributeType attr : oc.getRequiredAttributeChain()) { requiredAttrs.add(attr.getNameOrOID()); } Set parents = oc.getSuperiorClasses(); if (parents != null) { if (parents.size() > 1) { lParent.setText( INFO_CTRL_PANEL_OBJECTCLASS_PARENTS_LABEL.get().toString()); } else { lParent.setText( INFO_CTRL_PANEL_OBJECTCLASS_PARENT_LABEL.get().toString()); } for (ObjectClass parent : parents) { for (AttributeType attr : parent.getRequiredAttributeChain()) { inheritedAttrs.add(attr.getNameOrOID()); } } } else { lParent.setText( INFO_CTRL_PANEL_OBJECTCLASS_PARENT_LABEL.get().toString()); } DefaultListModel model = (DefaultListModel)requiredAttributes.getModel(); model.clear(); for (String attr : requiredAttrs) { String v; if (inheritedAttrs.contains(attr)) { v = attr+" (*)"; } else { v = attr; } model.addElement(v); hmAttrs.put(v, schema.getAttributeType(attr.toLowerCase())); } SortedSet optionalAttrs = new TreeSet<>(lowerCaseComparator); inheritedAttrs = new HashSet<>(); for (AttributeType attr : oc.getOptionalAttributeChain()) { optionalAttrs.add(attr.getNameOrOID()); } if (parents != null) { for (ObjectClass parent : parents) { for (AttributeType attr : parent.getOptionalAttributeChain()) { inheritedAttrs.add(attr.getNameOrOID()); } } } model = (DefaultListModel)optionalAttributes.getModel(); model.clear(); for (String attr : optionalAttrs) { String v; if (inheritedAttrs.contains(attr)) { v = attr+" (*)"; } else { v = attr; } model.addElement(v); hmAttrs.put(v, schema.getAttributeType(attr.toLowerCase())); } } private String getSuperiorText(ObjectClass oc) { String n; Set superiors = oc.getSuperiorClasses(); if (superiors == null) { n = null; } else { if (superiors.isEmpty()) { n = NOT_APPLICABLE.toString(); } else if (superiors.size() == 1) { n = superiors.iterator().next().getPrimaryName(); } else { SortedSet names = new TreeSet<>(); for (ObjectClass superior : superiors) { names.add(superior.getPrimaryName()); } n = Utilities.getStringFromCollection(names, ", "); } } if (n == null) { n = NOT_APPLICABLE.toString(); } return n; } /** * Returns the message describing the object class type (structural, obsolete, * etc.) of a given object class. * @param oc the object class. * @return the message describing the object class type (structural, obsolete, * etc.) of the provided object class. */ static LocalizableMessage getTypeValue(ObjectClass oc) { LocalizableMessageBuilder mb = new LocalizableMessageBuilder(); switch (oc.getObjectClassType()) { case ABSTRACT: mb.append(ABSTRACT_VALUE); break; case STRUCTURAL: mb.append(STRUCTURAL_VALUE); break; case AUXILIARY: mb.append(AUXILIARY_VALUE); break; } if (oc.isObsolete()) { if (mb.length() > 0) { mb.append(", "); } mb.append(OBSOLETE_VALUE); } return mb.toMessage(); } private void attrSelected(JList list) { String o = (String)list.getSelectedValue(); if (o != null) { AttributeType attr = hmAttrs.get(o); if (attr != null) { notifySchemaSelectionListeners(attr); } } } }