/**
   * This looks through a list of object classes in an attribute until it finds a unique editor
   * corresponding to a particular value. If no editor is found 'null' is returned. Note that If
   * multiple unique editors exist, which one is returned is undefined.
   *
   * <p>
   *
   * @param oc the objectClass attribute; a list of object classes
   * @return the unique pluggable editor corresponding to one particular object class value, or null
   *     if none is found.
   */
  public PluggableEditor getUniqueEditor(Attribute oc) {
    try {
      Enumeration values = oc.getAll();
      while (values.hasMoreElements()) {
        String objectClassName = (String) values.nextElement();

        PluggableEditor editor = getEditor(objectClassName);
        if (editor != null) {
          if (editor.isUnique()) return editor;
        }
      }
      return null;
    } catch (Exception e) {
      log.log(Level.FINE, "Unable to find unique pluggable editor: ", e);
      return null;
    }
  }
  /**
   * Clear out all the old editors, and get new editors corresponding to the new object classes.
   *
   * @param entry the entry to be displayed by all the editors
   * @param ds the datasource the editors may use for more info
   * @param ocs the object classes (in order) to find editors for.
   */
  protected void setEditors(DXEntry entry, DataBrokerQueryInterface ds, Vector ocs) {

    try {
      clearPluggableEditors(); // clear all extra editors

      // search for unique structural editors...

      if ("false".equalsIgnoreCase(JXConfig.getProperty("plugins.ignoreUniqueness"))) {
        if (ocs == null) // TE: may happen if virtual entry.
        return;

        int size = ocs.size();

        for (int i = 0; i < size; i++) {
          Object objectClass = ocs.get(i);
          if (objectClass != null) {
            PluggableEditor ed = getEditor(objectClass.toString());
            if (ed != null && ed.isUnique() == true) // found a unique editor
            { // so clear old ones,
              addUniqueEditor(ed); // and use the unique one
              refreshEditors(entry, ds); // to display the data
              setCurrentEditor(ed);
              return; // ... and exit.
            }
          }
        }
      } else log.warning("skipping uniqueness test for pluggable editors");

      boolean newEdSet = false;

      // search for non-unique structural editors
      for (int i = 0; i < ocs.size(); i++) {
        Object objectClass = ocs.get(i);
        if (objectClass != null) {
          PluggableEditor ed = getEditor(objectClass.toString());
          if (ed != null) {
            addEditor(ed);

            // Force the displayed editor to be the first pluggable one...
            if (newEdSet == false) {
              setCurrentEditor(ed);
              newEdSet = true;
            }
          }
        }
      }

      // search for non-structural editors
      try {
        Attribute allOCs = entry.getAllObjectClasses();
        if (allOCs != null) {
          Enumeration vals = allOCs.getAll();
          while (vals.hasMoreElements()) {
            Object oc = vals.nextElement();
            if (oc != null) {
              String ocName = oc.toString();
              if (ocs.contains(ocName)
                  == false) // don't bother with struct objectclasses dealt with above
              {
                PluggableEditor ed = getEditor(ocName);

                if (ed != null) {
                  addEditor(ed);

                  if (ed.isUnique()) // a special service to users...
                  log.warning(
                        "WARNING: Illegal unique editor defined for oc: "
                            + ocName
                            + " not allowed - (oc not in primary structural inheritance chain)");
                }
              }
            }
          }
        }
      } catch (NamingException e) {
        log.log(
            Level.WARNING,
            "WARNING: non-fatal exception getting object classes for plugin editors. ",
            e);
      }

      addEditor(templateDisplay); // and always add old faithfulls...
      // XXX
      if (entry.getStatus() != DXEntry.NEW) // well, almost always...
      addEditor(tableDisplay);
    } catch (Exception e) {
      log.warning("Unexpected Exception in AttributeDisplay\n" + e);
      e.printStackTrace();
    }
  }