001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2008-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2016 ForgeRock AS.
016 */
017package org.opends.guitools.controlpanel.ui;
018
019import static org.opends.messages.AdminToolMessages.*;
020
021import java.awt.Component;
022import java.awt.GridBagConstraints;
023import java.awt.GridBagLayout;
024import java.awt.event.ItemEvent;
025import java.awt.event.ItemListener;
026import java.io.File;
027import java.util.ArrayList;
028import java.util.Arrays;
029import java.util.HashMap;
030import java.util.LinkedHashSet;
031import java.util.List;
032import java.util.Map;
033import java.util.Set;
034import java.util.SortedSet;
035import java.util.TreeSet;
036
037import javax.swing.DefaultComboBoxModel;
038import javax.swing.JCheckBox;
039import javax.swing.JComboBox;
040import javax.swing.JLabel;
041import javax.swing.JPanel;
042import javax.swing.JTextField;
043import javax.swing.SwingUtilities;
044import javax.swing.event.ChangeEvent;
045import javax.swing.event.ChangeListener;
046
047import org.forgerock.i18n.LocalizableMessage;
048import org.forgerock.i18n.LocalizableMessageBuilder;
049import org.forgerock.opendj.ldap.schema.AttributeType;
050import org.forgerock.opendj.ldap.schema.AttributeUsage;
051import org.forgerock.opendj.ldap.schema.MatchingRule;
052import org.forgerock.opendj.ldap.schema.SchemaBuilder;
053import org.forgerock.opendj.ldap.schema.Syntax;
054import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
055import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
056import org.opends.guitools.controlpanel.event.ConfigurationElementCreatedListener;
057import org.opends.guitools.controlpanel.task.NewSchemaElementsTask;
058import org.opends.guitools.controlpanel.task.Task;
059import org.opends.guitools.controlpanel.ui.components.BasicExpander;
060import org.opends.guitools.controlpanel.ui.renderer.SchemaElementComboBoxCellRenderer;
061import org.opends.guitools.controlpanel.util.LowerCaseComparator;
062import org.opends.guitools.controlpanel.util.Utilities;
063import org.opends.server.config.ConfigConstants;
064import org.opends.server.types.ObjectClass;
065import org.opends.server.types.Schema;
066import org.opends.server.util.ServerConstants;
067import org.opends.server.util.StaticUtils;
068
069/** The panel displayed when the user wants to define a new attribute in the schema. */
070public class NewAttributePanel extends StatusGenericPanel
071{
072  private static final long serialVersionUID = 2340170241535771321L;
073
074  private static final LocalizableMessage NO_PARENT = INFO_CTRL_PANEL_NO_PARENT_FOR_ATTRIBUTE.get();
075  private static final LocalizableMessage NO_MATCHING_RULE = INFO_CTRL_PANEL_NO_MATCHING_RULE_FOR_ATTRIBUTE.get();
076
077  private final JLabel lName = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_ATTRIBUTE_NAME_LABEL.get());
078  private final JLabel lParent = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_ATTRIBUTE_PARENT_LABEL.get());
079  private final JLabel lOID = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_ATTRIBUTE_OID_LABEL.get());
080  private final JLabel lAliases = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_ATTRIBUTE_ALIASES_LABEL.get());
081  private final JLabel lOrigin = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_ATTRIBUTE_ORIGIN_LABEL.get());
082  private final JLabel lFile = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_ATTRIBUTE_FILE_LABEL.get());
083  private final JLabel lDescription = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_ATTRIBUTE_DESCRIPTION_LABEL.get());
084  private final JLabel lUsage = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_ATTRIBUTE_USAGE_LABEL.get());
085  private final JLabel lSyntax = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_ATTRIBUTE_SYNTAX_LABEL.get());
086  private final JLabel lApproximate = Utilities.createPrimaryLabel(
087      INFO_CTRL_PANEL_ATTRIBUTE_APPROXIMATE_MATCHING_RULE_LABEL.get());
088  private final JLabel lEquality = Utilities.createPrimaryLabel(
089      INFO_CTRL_PANEL_ATTRIBUTE_EQUALITY_MATCHING_RULE_LABEL.get());
090  private final JLabel lOrdering = Utilities.createPrimaryLabel(
091      INFO_CTRL_PANEL_ATTRIBUTE_ORDERING_MATCHING_RULE_LABEL.get());
092  private final JLabel lSubstring = Utilities.createPrimaryLabel(
093      INFO_CTRL_PANEL_ATTRIBUTE_SUBSTRING_MATCHING_RULE_LABEL.get());
094  private final JLabel lType = Utilities.createPrimaryLabel();
095
096  private final JLabel[] labels = { lName, lParent, lOID, lAliases, lOrigin, lFile, lDescription, lUsage, lSyntax,
097    lApproximate, lEquality, lOrdering, lSubstring, lType };
098
099  private final JTextField name = Utilities.createMediumTextField();
100  private final JComboBox parent = Utilities.createComboBox();
101  private final JTextField oid = Utilities.createMediumTextField();
102  private final JTextField aliases = Utilities.createLongTextField();
103  private final JTextField description = Utilities.createLongTextField();
104  private final JTextField origin = Utilities.createLongTextField();
105  private final JTextField file = Utilities.createLongTextField();
106  private final JComboBox<AttributeUsage> usage = Utilities.createComboBox();
107  private final JComboBox syntax = Utilities.createComboBox();
108  private final JComboBox approximate = Utilities.createComboBox();
109  private final JComboBox equality = Utilities.createComboBox();
110  private final JComboBox ordering = Utilities.createComboBox();
111  private final JComboBox substring = Utilities.createComboBox();
112  private final JCheckBox nonModifiable = Utilities.createCheckBox(
113      INFO_CTRL_PANEL_ATTRIBUTE_NON_MODIFIABLE_LABEL.get());
114  private final JCheckBox singleValued = Utilities.createCheckBox(INFO_CTRL_PANEL_ATTRIBUTE_SINGLE_VALUED_LABEL.get());
115  private final JCheckBox collective = Utilities.createCheckBox(INFO_CTRL_PANEL_ATTRIBUTE_COLLECTIVE_LABEL.get());
116  private final JCheckBox obsolete = Utilities.createCheckBox(INFO_CTRL_PANEL_ATTRIBUTE_OBSOLETE_LABEL.get());
117
118  private Schema schema;
119
120  private final Component relativeComponent;
121
122  /**
123   * Constructor of the new attribute panel.
124   *
125   * @param relativeComponent
126   *          the component relative to which the dialog containing this panel
127   *          must be centered.
128   */
129  public NewAttributePanel(Component relativeComponent)
130  {
131    this.relativeComponent = relativeComponent;
132    createLayout();
133  }
134
135  @Override
136  public LocalizableMessage getTitle()
137  {
138    return INFO_CTRL_PANEL_NEW_ATTRIBUTE_PANEL_TITLE.get();
139  }
140
141  @Override
142  public Component getPreferredFocusComponent()
143  {
144    return name;
145  }
146
147  @Override
148  public void configurationChanged(ConfigurationChangeEvent ev)
149  {
150    List<Syntax> newSyntaxes = new ArrayList<>();
151    final ServerDescriptor desc = ev.getNewDescriptor();
152    Schema s = desc.getSchema();
153
154    final boolean firstSchema = schema == null;
155    final boolean[] repack = { firstSchema };
156    final boolean[] error = { false };
157
158    boolean schemaChanged;
159    if (schema != null && s != null)
160    {
161      schemaChanged = !ServerDescriptor.areSchemasEqual(s, schema);
162    }
163    else if (schema == null && s != null)
164    {
165      schemaChanged = true;
166    }
167    else if (s == null && schema != null)
168    {
169      schemaChanged = false;
170    }
171    else
172    {
173      schemaChanged = false;
174    }
175    if (schemaChanged)
176    {
177      schema = s;
178      Map<String, Syntax> syntaxNameMap = new HashMap<>();
179
180      for (Syntax syntax : schema.getSyntaxes())
181      {
182        String name = syntax.getName();
183        if (name == null)
184        {
185          name = syntax.getOID();
186        }
187        syntaxNameMap.put(name, syntax);
188      }
189
190      SortedSet<String> orderedKeys = new TreeSet<>(new LowerCaseComparator());
191      orderedKeys.addAll(syntaxNameMap.keySet());
192      for (String key : orderedKeys)
193      {
194        newSyntaxes.add(syntaxNameMap.get(key));
195      }
196      updateComboBoxModel(newSyntaxes, (DefaultComboBoxModel) syntax.getModel());
197
198      Map<String, AttributeType> attributeNameMap = new HashMap<>();
199      for (AttributeType attr : schema.getAttributeTypes())
200      {
201        attributeNameMap.put(attr.getNameOrOID(), attr);
202      }
203      orderedKeys.clear();
204      orderedKeys.addAll(attributeNameMap.keySet());
205      List<Object> newParents = new ArrayList<>();
206      for (String key : orderedKeys)
207      {
208        newParents.add(attributeNameMap.get(key));
209      }
210      newParents.add(0, NO_PARENT);
211      updateComboBoxModel(newParents, (DefaultComboBoxModel) parent.getModel());
212
213      final List<MatchingRule> availableMatchingRules = new ArrayList<>();
214      final Map<String, MatchingRule> matchingRuleNameMap = new HashMap<>();
215      for (MatchingRule rule : schema.getMatchingRules())
216      {
217        matchingRuleNameMap.put(rule.getNameOrOID(), rule);
218      }
219
220      orderedKeys.clear();
221      orderedKeys.addAll(matchingRuleNameMap.keySet());
222      for (final String key : orderedKeys)
223      {
224        availableMatchingRules.add(matchingRuleNameMap.get(key));
225      }
226
227      final JComboBox<?>[] combos = { approximate, equality, ordering, substring };
228      for (JComboBox<?> combo : combos)
229      {
230        final DefaultComboBoxModel<?> model = (DefaultComboBoxModel<?>) combo.getModel();
231        final List<Object> el = new ArrayList<Object>(availableMatchingRules);
232        el.add(0, model.getSize() == 0 ? NO_MATCHING_RULE : model.getElementAt(0));
233        updateComboBoxModel(el, model);
234      }
235    }
236    else if (schema == null)
237    {
238      updateErrorPane(errorPane,
239          ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_SUMMARY.get(),
240          ColorAndFontConstants.errorTitleFont,
241          ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_DETAILS.get(),
242          ColorAndFontConstants.defaultFont);
243      repack[0] = true;
244      error[0] = true;
245    }
246    SwingUtilities.invokeLater(new Runnable()
247    {
248      @Override
249      public void run()
250      {
251        setEnabledOK(!error[0]);
252        errorPane.setVisible(error[0]);
253        if (firstSchema)
254        {
255          for (int i = 0; i < syntax.getModel().getSize(); i++)
256          {
257            Syntax syn = (Syntax) syntax.getModel().getElementAt(i);
258            if ("DirectoryString".equals(syn.getName()))
259            {
260              syntax.setSelectedIndex(i);
261              break;
262            }
263          }
264        }
265        else
266        {
267          updateDefaultMatchingRuleNames();
268        }
269
270        if (repack[0])
271        {
272          packParentDialog();
273          if (relativeComponent != null)
274          {
275            Utilities.centerGoldenMean(Utilities.getParentDialog(NewAttributePanel.this), relativeComponent);
276          }
277        }
278      }
279    });
280    if (!error[0])
281    {
282      updateErrorPaneAndOKButtonIfAuthRequired(desc,
283          isLocal() ? INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_TO_CREATE_ATTRIBUTE_SUMMARY.get()
284                    : INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get(desc.getHostname()));
285    }
286  }
287
288  @Override
289  public void okClicked()
290  {
291    List<LocalizableMessage> errors = new ArrayList<>();
292    for (JLabel label : labels)
293    {
294      setPrimaryValid(label);
295    }
296    String n = getAttributeName();
297    LocalizableMessageBuilder err = new LocalizableMessageBuilder();
298    if (n.length() == 0)
299    {
300      errors.add(ERR_CTRL_PANEL_ATTRIBUTE_NAME_REQUIRED.get());
301      setPrimaryInvalid(lName);
302    }
303    else if (!StaticUtils.isValidSchemaElement(n, 0, n.length(), err))
304    {
305      errors.add(ERR_CTRL_PANEL_INVALID_ATTRIBUTE_NAME.get(err));
306      setPrimaryInvalid(lName);
307      err = new LocalizableMessageBuilder();
308    }
309    else
310    {
311      LocalizableMessage elementType = getSchemaElementType(n, schema);
312      if (elementType != null)
313      {
314        errors.add(ERR_CTRL_PANEL_ATTRIBUTE_NAME_ALREADY_IN_USE.get(n, elementType));
315        setPrimaryInvalid(lName);
316      }
317    }
318
319    n = oid.getText().trim();
320    if (n.length() > 0)
321    {
322      if (!StaticUtils.isValidSchemaElement(n, 0, n.length(), err))
323      {
324        errors.add(ERR_CTRL_PANEL_OID_NOT_VALID.get(err));
325        setPrimaryInvalid(lOID);
326        err = new LocalizableMessageBuilder();
327      }
328      else
329      {
330        LocalizableMessage elementType = getSchemaElementType(n, schema);
331        if (elementType != null)
332        {
333          errors.add(ERR_CTRL_PANEL_OID_ALREADY_IN_USE.get(n, elementType));
334          setPrimaryInvalid(lOID);
335        }
336      }
337    }
338
339    if (aliases.getText().trim().length() > 0)
340    {
341      String[] al = aliases.getText().split(",");
342      if (al.length > 0)
343      {
344        for (String alias : al)
345        {
346          if (alias.trim().length() == 0)
347          {
348            errors.add(ERR_CTRL_PANEL_EMPTY_ALIAS.get());
349            setPrimaryInvalid(lAliases);
350          }
351          else
352          {
353            LocalizableMessage elementType = getSchemaElementType(alias, schema);
354            if (elementType != null)
355            {
356              errors.add(ERR_CTRL_PANEL_ALIAS_ALREADY_IN_USE.get(n, elementType));
357              setPrimaryInvalid(lAliases);
358            }
359          }
360        }
361      }
362    }
363
364    setPrimaryValid(lUsage);
365    if (nonModifiable.isSelected() && AttributeUsage.USER_APPLICATIONS.equals(usage.getSelectedItem()))
366    {
367      errors.add(ERR_NON_MODIFIABLE_CANNOT_BE_USER_APPLICATIONS.get());
368      setPrimaryInvalid(lUsage);
369    }
370
371    ProgressDialog dlg = new ProgressDialog(Utilities.createFrame(), Utilities.getParentDialog(this),
372        INFO_CTRL_PANEL_NEW_ATTRIBUTE_PANEL_TITLE.get(), getInfo());
373    NewSchemaElementsTask newTask = null;
374    if (errors.isEmpty())
375    {
376      Set<AttributeType> attributes = new LinkedHashSet<>();
377      attributes.add(getAttribute());
378      Set<ObjectClass> ocs = new LinkedHashSet<>(0);
379      newTask = new NewSchemaElementsTask(getInfo(), dlg, ocs, attributes);
380      for (Task task : getInfo().getTasks())
381      {
382        task.canLaunch(newTask, errors);
383      }
384      for (ConfigurationElementCreatedListener listener : getConfigurationElementCreatedListeners())
385      {
386        newTask.addConfigurationElementCreatedListener(listener);
387      }
388    }
389    if (errors.isEmpty())
390    {
391      String attrName = getAttributeName();
392      launchOperation(newTask,
393                      INFO_CTRL_PANEL_CREATING_ATTRIBUTE_SUMMARY.get(attrName),
394                      INFO_CTRL_PANEL_CREATING_ATTRIBUTE_COMPLETE.get(),
395                      INFO_CTRL_PANEL_CREATING_ATTRIBUTE_SUCCESSFUL.get(attrName),
396                      ERR_CTRL_PANEL_CREATING_ATTRIBUTE_ERROR_SUMMARY.get(),
397                      ERR_CTRL_PANEL_CREATING_ATTRIBUTE_ERROR_DETAILS.get(attrName),
398                      null,
399                      dlg);
400      dlg.setVisible(true);
401      name.setText("");
402      oid.setText("");
403      description.setText("");
404      aliases.setText("");
405      name.grabFocus();
406      Utilities.getParentDialog(this).setVisible(false);
407    }
408    else
409    {
410      displayErrorDialog(errors);
411    }
412  }
413
414  /**
415   * Returns the message representing the schema element type.
416   *
417   * @param name
418   *          the name of the schema element.
419   * @param schema
420   *          the schema.
421   * @return the message representing the schema element type.
422   */
423  static LocalizableMessage getSchemaElementType(String name, Schema schema)
424  {
425    final String lowerCase = name.toLowerCase();
426    if (schema.hasAttributeType(lowerCase))
427    {
428      return INFO_CTRL_PANEL_TYPE_ATTRIBUTE.get();
429    }
430    else if (schema.hasObjectClass(lowerCase))
431    {
432      return INFO_CTRL_PANEL_TYPE_OBJECT_CLASS.get();
433    }
434    else if (schema.hasSyntax(lowerCase))
435    {
436      return INFO_CTRL_PANEL_TYPE_ATTRIBUTE_SYNTAX.get();
437    }
438    else if (schema.hasMatchingRule(lowerCase))
439    {
440      return INFO_CTRL_PANEL_TYPE_MATCHING_RULE.get();
441    }
442
443    for (Syntax attr : schema.getSyntaxes())
444    {
445      if (name.equalsIgnoreCase(attr.getName()))
446      {
447        return INFO_CTRL_PANEL_TYPE_ATTRIBUTE_SYNTAX.get();
448      }
449    }
450
451    for (MatchingRule rule : schema.getMatchingRules())
452    {
453      String n = rule.getNameOrOID();
454      if (n != null && n.equalsIgnoreCase(name))
455      {
456        return INFO_CTRL_PANEL_TYPE_MATCHING_RULE.get();
457      }
458    }
459
460    return null;
461  }
462
463  /** Creates the layout of the panel (but the contents are not populated here). */
464  private void createLayout()
465  {
466    GridBagConstraints gbc = new GridBagConstraints();
467    Utilities.setRequiredIcon(lName);
468
469    gbc.gridwidth = 2;
470    gbc.gridy = 0;
471    addErrorPane(gbc);
472
473    gbc.gridy++;
474    gbc.gridwidth = 1;
475    gbc.weighty = 0.0;
476    gbc.gridx = 1;
477    gbc.anchor = GridBagConstraints.EAST;
478    gbc.fill = GridBagConstraints.NONE;
479    JLabel requiredLabel = createRequiredLabel();
480    gbc.insets.bottom = 10;
481    add(requiredLabel, gbc);
482
483    gbc.gridy++;
484    gbc.fill = GridBagConstraints.HORIZONTAL;
485    gbc.anchor = GridBagConstraints.WEST;
486    gbc.insets.bottom = 0;
487
488    JComboBox[] comboBoxes = { parent, syntax, approximate, equality, ordering, substring };
489    LocalizableMessage[] defaultValues =
490        { NO_PARENT, LocalizableMessage.EMPTY, NO_MATCHING_RULE, NO_MATCHING_RULE, NO_MATCHING_RULE, NO_MATCHING_RULE };
491    SchemaElementComboBoxCellRenderer renderer = new SchemaElementComboBoxCellRenderer(syntax);
492    for (int i = 0; i < comboBoxes.length; i++)
493    {
494      DefaultComboBoxModel model = new DefaultComboBoxModel(new Object[] { defaultValues[i] });
495      comboBoxes[i].setModel(model);
496      comboBoxes[i].setRenderer(renderer);
497    }
498
499    DefaultComboBoxModel<AttributeUsage> model = new DefaultComboBoxModel<>();
500    for (AttributeUsage us : AttributeUsage.values())
501    {
502      model.addElement(us);
503    }
504    usage.setModel(model);
505    usage.setSelectedItem(AttributeUsage.USER_APPLICATIONS);
506    usage.setRenderer(renderer);
507
508    Component[] basicComps = { name, oid, description, syntax };
509    JLabel[] basicLabels = { lName, lOID, lDescription, lSyntax };
510    JLabel[] basicInlineHelp = new JLabel[] {
511      null, null, null, Utilities.createInlineHelpLabel(INFO_CTRL_PANEL_SYNTAX_INLINE_HELP.get()) };
512    add(basicLabels, basicComps, basicInlineHelp, this, gbc);
513
514    BasicExpander[] expanders = new BasicExpander[] {
515          new BasicExpander(INFO_CTRL_PANEL_EXTRA_OPTIONS_EXPANDER.get()),
516          new BasicExpander(INFO_CTRL_PANEL_ATTRIBUTE_TYPE_OPTIONS_EXPANDER.get()),
517          new BasicExpander(INFO_CTRL_PANEL_MATCHING_RULE_OPTIONS_EXPANDER.get()) };
518
519    Component[][] comps = { { parent, aliases, origin, file },
520                            { usage, singleValued, nonModifiable, collective, obsolete },
521                            { approximate, equality, ordering, substring } };
522    JLabel[][] labels ={ { lParent, lAliases, lOrigin, lFile },
523                         { lUsage, lType, null, null, null },
524                         { lApproximate, lEquality, lOrdering, lSubstring } };
525    JLabel[][] inlineHelps = {
526          { null, Utilities.createInlineHelpLabel(INFO_CTRL_PANEL_SEPARATED_WITH_COMMAS_HELP.get()), null,
527            Utilities.createInlineHelpLabel(INFO_CTRL_PANEL_SCHEMA_FILE_ATTRIBUTE_HELP.get(File.separator)) },
528          { null, null, null, null, null, null },
529          { Utilities.createInlineHelpLabel(INFO_CTRL_PANEL_MATCHING_RULE_APPROXIMATE_HELP.get()),
530            Utilities.createInlineHelpLabel(INFO_CTRL_PANEL_MATCHING_RULE_EQUALITY_HELP.get()),
531            Utilities.createInlineHelpLabel(INFO_CTRL_PANEL_MATCHING_RULE_ORDERING_HELP.get()),
532            Utilities.createInlineHelpLabel(INFO_CTRL_PANEL_MATCHING_RULE_SUBSTRING_HELP.get()) } };
533    for (int i = 0; i < expanders.length; i++)
534    {
535      gbc.gridwidth = 2;
536      gbc.gridx = 0;
537      gbc.insets.left = 0;
538      add(expanders[i], gbc);
539      final JPanel p = new JPanel(new GridBagLayout());
540      gbc.insets.left = 15;
541      gbc.gridy++;
542      add(p, gbc);
543      gbc.gridy++;
544      p.setOpaque(false);
545
546      GridBagConstraints gbc1 = new GridBagConstraints();
547      gbc1.fill = GridBagConstraints.HORIZONTAL;
548      gbc1.gridy = 0;
549
550      add(labels[i], comps[i], inlineHelps[i], p, gbc1);
551      final BasicExpander expander = expanders[i];
552      ChangeListener changeListener = new ChangeListener()
553      {
554        @Override
555        public void stateChanged(ChangeEvent e)
556        {
557          p.setVisible(expander.isSelected());
558        }
559      };
560      expander.addChangeListener(changeListener);
561      expander.setSelected(false);
562      changeListener.stateChanged(null);
563    }
564    addBottomGlue(gbc);
565
566    ItemListener itemListener = new ItemListener()
567    {
568      @Override
569      public void itemStateChanged(ItemEvent ev)
570      {
571        if (ev.getStateChange() == ItemEvent.SELECTED)
572        {
573          updateDefaultMatchingRuleNames();
574          approximate.setSelectedIndex(0);
575          substring.setSelectedIndex(0);
576          equality.setSelectedIndex(0);
577          ordering.setSelectedIndex(0);
578        }
579      }
580    };
581    syntax.addItemListener(itemListener);
582
583    file.setText(ConfigConstants.FILE_USER_SCHEMA_ELEMENTS);
584  }
585
586  private void updateDefaultMatchingRuleNames()
587  {
588    Syntax syn = (Syntax) syntax.getSelectedItem();
589    if (syn != null)
590    {
591      MatchingRule[] rules = { syn.getApproximateMatchingRule(), syn.getSubstringMatchingRule(),
592        syn.getEqualityMatchingRule(), syn.getOrderingMatchingRule() };
593      JComboBox[] combos = { approximate, substring, equality, ordering };
594      for (int i = 0; i < rules.length; i++)
595      {
596        DefaultComboBoxModel model = (DefaultComboBoxModel) combos[i].getModel();
597        int index = combos[i].getSelectedIndex();
598        if (model.getSize() > 0)
599        {
600          model.removeElementAt(0);
601        }
602
603        final LocalizableMessage msg =
604            rules[i] != null ? INFO_CTRL_PANEL_DEFAULT_DEFINED_IN_SYNTAX.get(rules[i].getNameOrOID())
605                             : NO_MATCHING_RULE;
606        model.insertElementAt(msg, 0);
607        combos[i].setSelectedIndex(index);
608      }
609    }
610  }
611
612  private String getAttributeName()
613  {
614    return name.getText().trim();
615  }
616
617  private String getOID()
618  {
619    String o = oid.getText().trim();
620    if (o.length() == 0)
621    {
622      o = getAttributeName() + "-oid";
623    }
624    return o;
625  }
626
627  private List<String> getAliases()
628  {
629    List<String> al = new ArrayList<>();
630    String s = aliases.getText().trim();
631    if (s.length() > 0)
632    {
633      String[] a = s.split(",");
634      for (String alias : a)
635      {
636        al.add(alias.trim());
637      }
638    }
639    return al;
640  }
641
642  private List<String> getAllNames()
643  {
644    List<String> al = new ArrayList<>();
645    al.add(getAttributeName());
646    al.addAll(getAliases());
647    return al;
648  }
649
650  private AttributeType getSuperior()
651  {
652    Object o = parent.getSelectedItem();
653    if (NO_PARENT.equals(o))
654    {
655      return null;
656    }
657    return (AttributeType) o;
658  }
659
660  private MatchingRule getApproximateMatchingRule()
661  {
662    return getMatchingRule(approximate);
663  }
664
665  private MatchingRule getEqualityMatchingRule()
666  {
667    return getMatchingRule(equality);
668  }
669
670  private MatchingRule getSubstringMatchingRule()
671  {
672    return getMatchingRule(substring);
673  }
674
675  private MatchingRule getOrderingMatchingRule()
676  {
677    return getMatchingRule(ordering);
678  }
679
680  private MatchingRule getMatchingRule(JComboBox comboBox)
681  {
682    if (comboBox.getSelectedIndex() != 0)
683    {
684      return (MatchingRule) comboBox.getSelectedItem();
685    }
686    return null;
687  }
688
689  private Map<String, List<String>> getExtraProperties()
690  {
691    final Map<String, List<String>> map = new HashMap<>();
692    addExtraPropertyFromTextField(file, ServerConstants.SCHEMA_PROPERTY_FILENAME, map);
693    addExtraPropertyFromTextField(origin, ServerConstants.SCHEMA_PROPERTY_ORIGIN, map);
694    return map;
695  }
696
697  private void addExtraPropertyFromTextField(
698      final JTextField value, final String key, final Map<String, List<String>> map)
699  {
700    final String trimmedValue = value.getText().trim();
701    if (!trimmedValue.trim().isEmpty())
702    {
703      map.put(key, Arrays.asList(trimmedValue));
704    }
705  }
706
707  private String getDescription()
708  {
709    return description.getText().trim();
710  }
711
712  private AttributeType getAttribute()
713  {
714    return new SchemaBuilder().buildAttributeType(getOID())
715      .names(getAllNames())
716      .description(getDescription())
717      .superiorType(getSuperior().getNameOrOID())
718      .syntax(((Syntax) syntax.getSelectedItem()).getOID())
719      .approximateMatchingRule(getApproximateMatchingRule().getOID())
720      .equalityMatchingRule(getEqualityMatchingRule().getOID())
721      .orderingMatchingRule(getOrderingMatchingRule().getOID())
722      .substringMatchingRule(getSubstringMatchingRule().getOID())
723      .usage((AttributeUsage)usage.getSelectedItem())
724      .collective(collective.isSelected())
725      .obsolete(obsolete.isSelected())
726      .noUserModification(nonModifiable.isSelected())
727      .singleValue(singleValued.isSelected())
728      .extraProperties(getExtraProperties())
729      .addToSchema()
730      .toSchema()
731      .getAttributeType(getOID());
732  }
733}