/**
   * We have to resort to manual validation otherwise the ajax tricks performed by the drop down
   * won't work
   */
  protected boolean validate() {
    boolean valid = true;
    if (attribute.getName() == null || attribute.getName().trim().equals("")) {
      nameField.error((IValidationError) new ValidationError().addMessageKey("Required"));
      valid = false;
    }
    if (String.class.equals(attribute.getBinding())) {
      try {
        attribute.setSize(Integer.parseInt(size));
        if (attribute.getSize() <= 0) {
          sizeField.error(new ParamResourceModel("notPositive", this));
          valid = false;
        }
      } catch (Exception e) {
        sizeField.error(new ParamResourceModel("notInteger", this, size));
        valid = false;
      }
    }
    if (Geometry.class.isAssignableFrom(attribute.getBinding()) && attribute.getCrs() == null) {
      crsField.error((IValidationError) new ValidationError().addMessageKey("Required"));
      valid = false;
    }

    return valid;
  }
  void loadDescription(ResultSet resultSet) throws SQLException, PlatformException {

    int descriptionID = resultSet.getInt("attributeset_item_id");
    String type = resultSet.getString("attribute_type");
    String name = resultSet.getString("attribute_name");
    String tableName = resultSet.getString("table_name");
    String columnName = resultSet.getString("column_name");
    boolean isOutput = resultSet.getString("is_output").equals("Y");

    AttributeDescription description =
        (AttributeDescription)
            _attributeManager.createAttributeDescription(
                name, tableName, columnName, type, isOutput);
    description.setOutput(isOutput);

    // FIXME: if attribute type is enum, reading the value additionally
    if (AttributeType.ENUM.equals(type) && description instanceof EnumAttributeDescription) {
      String stringValue = resultSet.getString("attribute_value");
      ((EnumAttributeDescription) description).parseValues(stringValue);
    }

    ((AttributeDescription) description).setDescriptionID(descriptionID);
    _descriptions.add(description);
  }
  public void reload(DatasetConfigTreeNode editingNode, DatasetConfigTreeNode parentNode) {
    int start, finish;
    String parentClassName = (parentNode.getUserObject().getClass()).getName();
    String childClassName = (editingNode.getUserObject().getClass()).getName();
    start = childClassName.lastIndexOf(".") + 1;
    finish = childClassName.length();
    String childName = childClassName.substring(start, finish);
    if (parentClassName.equals("org.ensembl.mart.lib.config.DatasetConfig")) {
      if (childClassName.equals("org.ensembl.mart.lib.config.FilterPage")) {
        config = (DatasetConfig) parentNode.getUserObject();
        config.addFilterPage((FilterPage) editingNode.getUserObject());
        // config.removeAttributePage();

      } else if (childClassName.equals("org.ensembl.mart.lib.config.AttributePage")) {
        config = (DatasetConfig) parentNode.getUserObject();
        config.addAttributePage((AttributePage) editingNode.getUserObject());

      } else if (childClassName.equals("org.ensembl.mart.lib.config.Importable")) {
        config = (DatasetConfig) parentNode.getUserObject();
        config.addImportable((Importable) editingNode.getUserObject());

      } else if (childClassName.equals("org.ensembl.mart.lib.config.Exportable")) {
        config = (DatasetConfig) parentNode.getUserObject();
        config.addExportable((Exportable) editingNode.getUserObject());
      }
    } else if (parentClassName.equals("org.ensembl.mart.lib.config.FilterPage")) {
      if (childClassName.equals("org.ensembl.mart.lib.config.FilterGroup")) {
        FilterPage fp = (FilterPage) parentNode.getUserObject();
        fp.addFilterGroup((FilterGroup) editingNode.getUserObject());
      }
    } else if (parentClassName.equals("org.ensembl.mart.lib.config.FilterGroup")) {
      if (childClassName.equals("org.ensembl.mart.lib.config.FilterCollection")) {
        FilterGroup fg = (FilterGroup) parentNode.getUserObject();
        fg.addFilterCollection((FilterCollection) editingNode.getUserObject());
      }
    } else if (parentClassName.equals("org.ensembl.mart.lib.config.FilterCollection")) {
      if (childClassName.equals("org.ensembl.mart.lib.config.FilterDescription")) {
        FilterCollection fc = (FilterCollection) parentNode.getUserObject();
        fc.addFilterDescription((FilterDescription) editingNode.getUserObject());
      }
    } else if (parentClassName.equals("org.ensembl.mart.lib.config.FilterDescription")) {

      if (childClassName.equals("org.ensembl.mart.lib.config.Option")) {
        FilterDescription fd = (FilterDescription) parentNode.getUserObject();
        fd.addOption((Option) editingNode.getUserObject());

      } else if (childClassName.equals("org.ensembl.mart.lib.config.SpecificFilterContent")) {
        FilterDescription ad = (FilterDescription) parentNode.getUserObject();
        ad.addSpecificFilterContent((SpecificFilterContent) editingNode.getUserObject());
      }

    } else if (parentClassName.equals("org.ensembl.mart.lib.config.Option")) {
      if (childClassName.equals("org.ensembl.mart.lib.config.SpecificOptionContent")) {
        Option ad = (Option) parentNode.getUserObject();
        ad.addSpecificOptionContent((SpecificOptionContent) editingNode.getUserObject());
      } else if (childClassName.equals("org.ensembl.mart.lib.config.PushAction")) {
        Option op = (Option) parentNode.getUserObject();
        op.addPushAction((PushAction) editingNode.getUserObject());
      } else if (childClassName.equals("org.ensembl.mart.lib.config.Option")) {
        Option op = (Option) parentNode.getUserObject();
        op.addOption((Option) editingNode.getUserObject());
      }
    } else if (parentClassName.equals("org.ensembl.mart.lib.config.PushAction")) {
      if (childClassName.equals("org.ensembl.mart.lib.config.Option")) {
        PushAction pa = (PushAction) parentNode.getUserObject();
        pa.addOption((Option) editingNode.getUserObject());
      }
    } else if (parentClassName.equals("org.ensembl.mart.lib.config.AttributePage")) {
      if (childClassName.equals("org.ensembl.mart.lib.config.AttributeGroup")) {
        AttributePage ap = (AttributePage) parentNode.getUserObject();
        ap.addAttributeGroup((AttributeGroup) editingNode.getUserObject());
      }
    } else if (parentClassName.equals("org.ensembl.mart.lib.config.AttributeGroup")) {
      if (childClassName.equals("org.ensembl.mart.lib.config.AttributeCollection")) {
        AttributeGroup ag = (AttributeGroup) parentNode.getUserObject();
        ag.addAttributeCollection((AttributeCollection) editingNode.getUserObject());
      }
    } else if (parentClassName.equals("org.ensembl.mart.lib.config.AttributeCollection")) {
      if (childClassName.equals("org.ensembl.mart.lib.config.AttributeDescription")) {
        AttributeCollection ac = (AttributeCollection) parentNode.getUserObject();
        ac.addAttributeDescription((AttributeDescription) editingNode.getUserObject());
      } else if (childClassName.equals("org.ensembl.mart.lib.config.AttributeList")) {
        AttributeCollection ac = (AttributeCollection) parentNode.getUserObject();
        ac.addAttributeList((AttributeList) editingNode.getUserObject());
      }
    } else if (parentClassName.equals("org.ensembl.mart.lib.config.AttributeDescription")) {

      if (childClassName.equals("org.ensembl.mart.lib.config.SpecificAttributeContent")) {
        AttributeDescription ad = (AttributeDescription) parentNode.getUserObject();
        ad.addSpecificAttributeContent((SpecificAttributeContent) editingNode.getUserObject());
      }

    } else if (parentClassName.equals("org.ensembl.mart.lib.config.SpecificFilterContent")) {
      if (childClassName.equals("org.ensembl.mart.lib.config.Option")) {
        SpecificFilterContent fd = (SpecificFilterContent) parentNode.getUserObject();
        System.out.println(
            "TREE MODEL -- ADDING DYN OPTION "
                + ((Option) editingNode.getUserObject()).getInternalName());
        fd.addOption((Option) editingNode.getUserObject());
      }
    }

    super.reload(parentNode);
  }
 public void removeNodeFromParent(DatasetConfigTreeNode node) {
   Object child = node.getUserObject();
   if (node.getParent() == null) return; // Can't remove root node.
   Object parent = ((DatasetConfigTreeNode) node.getParent()).getUserObject();
   if (parent instanceof org.ensembl.mart.lib.config.DatasetConfig) {
     if (child instanceof org.ensembl.mart.lib.config.FilterPage) {
       config = (DatasetConfig) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       config.removeFilterPage((FilterPage) node.getUserObject());
     } else if (child instanceof org.ensembl.mart.lib.config.AttributePage) {
       config = (DatasetConfig) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       config.removeAttributePage((AttributePage) node.getUserObject());
     } else if (child instanceof org.ensembl.mart.lib.config.Exportable) {
       config = (DatasetConfig) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       config.removeExportable((Exportable) node.getUserObject());
     } else if (child instanceof org.ensembl.mart.lib.config.Importable) {
       config = (DatasetConfig) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       config.removeImportable((Importable) node.getUserObject());
     }
   } else if (node.getUserObject() instanceof DynamicDataset) {
     config =
         (DatasetConfig) ((DatasetConfigTreeNode) node.getParent().getParent()).getUserObject();
     config.removeDynamicDataset((DynamicDataset) node.getUserObject());
   } else if (parent instanceof org.ensembl.mart.lib.config.FilterPage) {
     if (child instanceof org.ensembl.mart.lib.config.FilterGroup) {
       FilterPage fp = (FilterPage) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       fp.removeFilterGroup((FilterGroup) node.getUserObject());
     }
   } else if (parent instanceof org.ensembl.mart.lib.config.FilterGroup) {
     if (child instanceof org.ensembl.mart.lib.config.FilterCollection) {
       FilterGroup fg = (FilterGroup) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       fg.removeFilterCollection((FilterCollection) node.getUserObject());
     }
   } else if (parent instanceof org.ensembl.mart.lib.config.FilterCollection) {
     if (child instanceof org.ensembl.mart.lib.config.FilterDescription) {
       FilterCollection fc =
           (FilterCollection) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       fc.removeFilterDescription((FilterDescription) node.getUserObject());
     }
   } else if (parent instanceof org.ensembl.mart.lib.config.FilterDescription) {
     if (child instanceof org.ensembl.mart.lib.config.Option) {
       FilterDescription fd =
           (FilterDescription) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       fd.removeOption((Option) node.getUserObject());
     } else if (child instanceof org.ensembl.mart.lib.config.SpecificFilterContent) {
       FilterDescription ad =
           (FilterDescription) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       ad.removeSpecificFilterContent((SpecificFilterContent) node.getUserObject());
     }
   } else if (parent instanceof org.ensembl.mart.lib.config.Option) {
     if (child instanceof org.ensembl.mart.lib.config.SpecificOptionContent) {
       Option ad = (Option) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       ad.removeSpecificOptionContent((SpecificOptionContent) node.getUserObject());
     } else if (child instanceof org.ensembl.mart.lib.config.PushAction) {
       Option op = (Option) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       op.removePushAction((PushAction) node.getUserObject());
     } else if (child instanceof org.ensembl.mart.lib.config.Option) {
       Option fd = (Option) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       fd.removeOption((Option) node.getUserObject());
     }
   } else if (parent instanceof org.ensembl.mart.lib.config.PushAction) {
     if (child instanceof org.ensembl.mart.lib.config.Option) {
       PushAction pa = (PushAction) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       pa.removeOption((Option) node.getUserObject());
     }
   } else if (parent instanceof org.ensembl.mart.lib.config.AttributePage) {
     if (child instanceof org.ensembl.mart.lib.config.AttributeGroup) {
       AttributePage ap =
           (AttributePage) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       ap.removeAttributeGroup((AttributeGroup) node.getUserObject());
     }
   } else if (parent instanceof org.ensembl.mart.lib.config.AttributeGroup) {
     if (child instanceof org.ensembl.mart.lib.config.AttributeCollection) {
       AttributeGroup ag =
           (AttributeGroup) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       ag.removeAttributeCollection((AttributeCollection) node.getUserObject());
     }
   } else if (parent instanceof org.ensembl.mart.lib.config.AttributeCollection) {
     if (child instanceof org.ensembl.mart.lib.config.AttributeDescription) {
       AttributeCollection ac =
           (AttributeCollection) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       ac.removeAttributeDescription((AttributeDescription) node.getUserObject());
     } else if (child instanceof org.ensembl.mart.lib.config.AttributeList) {
       AttributeCollection ac =
           (AttributeCollection) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       ac.removeAttributeList((AttributeList) node.getUserObject());
     }
   } else if (parent instanceof org.ensembl.mart.lib.config.AttributeDescription) {
     if (child instanceof org.ensembl.mart.lib.config.SpecificAttributeContent) {
       AttributeDescription ad =
           (AttributeDescription) ((DatasetConfigTreeNode) node.getParent()).getUserObject();
       ad.removeSpecificAttributeContent((SpecificAttributeContent) node.getUserObject());
     }
   }
   super.removeNodeFromParent(node);
 }
  public String insertNodeInto(
      DatasetConfigTreeNode editingNode, DatasetConfigTreeNode parentNode, int index) {
    int start, finish;
    Object child = editingNode.getUserObject();
    Object parent = parentNode.getUserObject();
    BaseNamedConfigurationObject parentObj = (BaseNamedConfigurationObject) parent;
    BaseNamedConfigurationObject childObj = (BaseNamedConfigurationObject) child;
    if (parentObj.getHidden() != null && parentObj.getHidden().equals("true")) {
      childObj.setHidden("true");
      Enumeration children = editingNode.breadthFirstEnumeration();
      DatasetConfigTreeNode childNode = null;
      while (children.hasMoreElements()) {
        childNode = (DatasetConfigTreeNode) children.nextElement();
        BaseNamedConfigurationObject ch = (BaseNamedConfigurationObject) childNode.getUserObject();
        ch.setHidden("true");
      }
    }

    String childClassName = (editingNode.getUserObject().getClass()).getName();
    start = childClassName.lastIndexOf(".") + 1;
    finish = childClassName.length();
    String childName = childClassName.substring(start, finish);

    // index is a Node index. objectIndex may be different
    int objIndex = index - DatasetConfigTreeNode.getHeterogenousOffset(parent, child);
    if (parent instanceof org.ensembl.mart.lib.config.DatasetConfig) {
      if (child instanceof org.ensembl.mart.lib.config.FilterPage) {
        config = (DatasetConfig) parentNode.getUserObject();
        config.insertFilterPage(objIndex, (FilterPage) editingNode.getUserObject());

      } else if (child instanceof org.ensembl.mart.lib.config.AttributePage) {
        config = (DatasetConfig) parentNode.getUserObject();
        config.insertAttributePage(objIndex, (AttributePage) editingNode.getUserObject());

      } else if (child instanceof org.ensembl.mart.lib.config.Importable) {
        config = (DatasetConfig) parentNode.getUserObject();
        config.insertImportable(objIndex, (Importable) editingNode.getUserObject());

      } else if (child instanceof org.ensembl.mart.lib.config.Exportable) {
        config = (DatasetConfig) parentNode.getUserObject();
        config.insertExportable(objIndex, (Exportable) editingNode.getUserObject());
      } else {
        String error_string = "Error: " + childName + " cannot be inserted in a DatasetConfig.";
        return error_string;
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.FilterPage) {
      if (child instanceof org.ensembl.mart.lib.config.FilterGroup) {
        FilterPage fp = (FilterPage) parentNode.getUserObject();
        fp.insertFilterGroup(objIndex, (FilterGroup) editingNode.getUserObject());
      } else {
        String error_string = "Error: " + childName + " cannot be inserted in a FilterPage.";
        return error_string;
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.FilterGroup) {
      if (child instanceof org.ensembl.mart.lib.config.FilterCollection) {
        FilterGroup fg = (FilterGroup) parentNode.getUserObject();
        fg.insertFilterCollection(objIndex, (FilterCollection) editingNode.getUserObject());
      } else {
        String error_string = "Error: " + childName + " cannot be inserted in a FilterGroup.";
        return error_string;
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.FilterCollection) {
      if (child instanceof org.ensembl.mart.lib.config.FilterDescription) {
        FilterCollection fc = (FilterCollection) parentNode.getUserObject();
        fc.insertFilterDescription(objIndex, (FilterDescription) editingNode.getUserObject());
      } else if (child instanceof org.ensembl.mart.lib.config.Option) {
        FilterCollection fc = (FilterCollection) parentNode.getUserObject();
        FilterDescription fdConvert = new FilterDescription((Option) editingNode.getUserObject());
        fc.insertFilterDescription(objIndex, fdConvert);
        editingNode.setUserObject(fdConvert);
      } else if (child instanceof org.ensembl.mart.lib.config.AttributeDescription) {
        FilterCollection fc = (FilterCollection) parentNode.getUserObject();
        // FilterDescription fdConvert = new FilterDescription((AttributeDescription)
        // editingNode.getUserObject());
        AttributeDescription ad = (AttributeDescription) editingNode.getUserObject();

        FilterDescription fdConvert = null;
        try {
          fdConvert =
              new FilterDescription(
                  ad.getInternalName(),
                  ad.getField(),
                  "text",
                  "=",
                  "=",
                  ad.getDisplayName(),
                  ad.getTableConstraint(),
                  ad.getKey(),
                  ad.getDescription(),
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "",
                  "");
        } catch (ConfigurationException e) {
          // guaranteed internal name for atts
        }
        fc.insertFilterDescription(objIndex, fdConvert);
        editingNode.setUserObject(fdConvert);
      } else {
        String error_string = "Error: " + childName + " cannot be inserted in a FilterCollection.";
        return error_string;
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.FilterDescription) {
      if (child instanceof org.ensembl.mart.lib.config.SpecificFilterContent) {
        FilterDescription ad = (FilterDescription) parentNode.getUserObject();
        ad.insertSpecificFilterContent(
            objIndex, (SpecificFilterContent) editingNode.getUserObject());
      } else if (child instanceof org.ensembl.mart.lib.config.FilterDescription) {
        FilterDescription fd = (FilterDescription) parentNode.getUserObject();
        Option opConvert = new Option((FilterDescription) editingNode.getUserObject());
        fd.insertOption(objIndex, opConvert);
        editingNode.setUserObject(opConvert);
      } else if (child instanceof org.ensembl.mart.lib.config.Option) {
        FilterDescription fd = (FilterDescription) parentNode.getUserObject();
        fd.insertOption(objIndex, (Option) editingNode.getUserObject());
      } else if (child instanceof org.ensembl.mart.lib.config.PushAction) {
        FilterDescription fd = (FilterDescription) parentNode.getUserObject();
        // fd.insertPushAction(objIndex, (PushAction) editingNode.getUserObject());
      } else {
        String error_string = "Error: " + childName + " cannot be inserted in a FilterDescription.";
        return error_string;
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.Option) {
      if (child instanceof org.ensembl.mart.lib.config.SpecificOptionContent) {
        Option ad = (Option) parentNode.getUserObject();
        ad.insertSpecificOptionContent(
            objIndex, (SpecificOptionContent) editingNode.getUserObject());
      } else if (child instanceof org.ensembl.mart.lib.config.PushAction) {
        Option op = (Option) parentNode.getUserObject();
        op.insertPushAction(objIndex, (PushAction) editingNode.getUserObject());
      } else if (child instanceof org.ensembl.mart.lib.config.Option) {
        Option op = (Option) parentNode.getUserObject();
        op.insertOption(objIndex, (Option) editingNode.getUserObject());
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.PushAction) {
      if (child instanceof org.ensembl.mart.lib.config.Option) {
        PushAction pa = (PushAction) parentNode.getUserObject();
        pa.insertOption(objIndex, (Option) editingNode.getUserObject());
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.AttributePage) {
      if (child instanceof org.ensembl.mart.lib.config.AttributeGroup) {
        AttributePage ap = (AttributePage) parentNode.getUserObject();
        ap.insertAttributeGroup(objIndex, (AttributeGroup) editingNode.getUserObject());
      } else {
        String error_string = "Error: " + childName + " cannot be inserted in an AttributePage.";
        return error_string;
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.AttributeGroup) {
      if (child instanceof org.ensembl.mart.lib.config.AttributeCollection) {
        AttributeGroup ag = (AttributeGroup) parentNode.getUserObject();
        ag.insertAttributeCollection(objIndex, (AttributeCollection) editingNode.getUserObject());
      } else {
        String error_string = "Error: " + childName + " cannot be inserted in an AttributeGroup.";
        return error_string;
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.AttributeCollection) {
      if (child instanceof org.ensembl.mart.lib.config.AttributeDescription) {
        AttributeCollection ac = (AttributeCollection) parentNode.getUserObject();
        ac.insertAttributeDescription(objIndex, (AttributeDescription) editingNode.getUserObject());
      } else if (child instanceof org.ensembl.mart.lib.config.AttributeList) {
        AttributeCollection ac = (AttributeCollection) parentNode.getUserObject();
        ac.insertAttributeList(objIndex, (AttributeList) editingNode.getUserObject());
      } else {
        String error_string =
            "Error: " + childName + " cannot be inserted in an AttributeCollection.";
        return error_string;
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.AttributeDescription) {
      if (child instanceof org.ensembl.mart.lib.config.SpecificAttributeContent) {
        AttributeDescription ad = (AttributeDescription) parentNode.getUserObject();
        ad.insertSpecificAttributeContent(
            objIndex, (SpecificAttributeContent) editingNode.getUserObject());
      } else {
        String error_string = "Error: " + childName + " cannot be inserted in a FilterDescription.";
        return error_string;
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.SpecificFilterContent) {
      if (child instanceof org.ensembl.mart.lib.config.Option) {
        SpecificFilterContent fd = (SpecificFilterContent) parentNode.getUserObject();
        System.out.println(
            "TREE MODEL 2 -- ADDING DYN OPTION "
                + ((Option) editingNode.getUserObject()).getInternalName());

        fd.insertOption(objIndex, (Option) editingNode.getUserObject());
      } else {
        String error_string =
            "Error: " + childName + " cannot be inserted in an DynamicFilterContent.";
        return error_string;
      }
    } else if (parent instanceof org.ensembl.mart.lib.config.SpecificAttributeContent) {
      String error_string =
          "Error: " + childName + " cannot be inserted in an DynamicAttributeContent.";
      return error_string;
    } else if (parent instanceof org.ensembl.mart.lib.config.SpecificOptionContent) {
      String error_string =
          "Error: " + childName + " cannot be inserted in an DynamicOptionContent.";
      return error_string;
    }
    super.insertNodeInto(editingNode, parentNode, index);
    return "success";
  }
Example #6
0
/**
 * The root DSE is a DSA-specific Entry (DSE) and not part of any naming context (or any subtree),
 * and which is uniquely identified by the empty DN.
 *
 * <p>A Directory Server uses the root DSE to provide information about itself using the following
 * set of attributes:
 *
 * <ul>
 *   <li>{@code altServer}: alternative Directory Servers
 *   <li>{@code namingContexts}: naming contexts
 *   <li>{@code supportedControl}: recognized LDAP controls
 *   <li>{@code supportedExtension}: recognized LDAP extended operations
 *   <li>{@code supportedFeatures}: recognized LDAP features
 *   <li>{@code supportedLDAPVersion}: LDAP versions supported
 *   <li>{@code supportedSASLMechanisms}: recognized SASL authentication mechanisms
 *   <li>{@code supportedAuthPasswordSchemes}: recognized authentication password schemes
 *   <li>{@code subschemaSubentry}: the name of the subschema subentry holding the schema
 *       controlling the Root DSE
 *   <li>{@code vendorName}: the name of the Directory Server implementer
 *   <li>{@code vendorVersion}: the version of the Directory Server implementation.
 * </ul>
 *
 * The values provided for these attributes may depend on session- specific and other factors. For
 * example, a server supporting the SASL EXTERNAL mechanism might only list "EXTERNAL" when the
 * client's identity has been established by a lower level.
 *
 * <p>The root DSE may also include a {@code subschemaSubentry} attribute. If it does, the attribute
 * refers to the subschema (sub)entry holding the schema controlling the root DSE. Clients SHOULD
 * NOT assume that this subschema (sub)entry controls other entries held by the server.
 *
 * @see <a href="http://tools.ietf.org/html/rfc4512">RFC 4512 - Lightweight Directory Access
 *     Protocol (LDAP): Directory Information Models </a>
 * @see <a href="http://tools.ietf.org/html/rfc3045">RFC 3045 - Storing Vendor Information in the
 *     LDAP Root DSE </a>
 * @see <a href="http://tools.ietf.org/html/rfc3112">RFC 3112 - LDAP Authentication Password Schema
 *     </a>
 */
public final class RootDSE {
  private static final AttributeDescription ATTR_ALT_SERVER =
      AttributeDescription.create(CoreSchema.getAltServerAttributeType());

  private static final AttributeDescription ATTR_NAMING_CONTEXTS =
      AttributeDescription.create(CoreSchema.getNamingContextsAttributeType());

  private static final AttributeDescription ATTR_SUBSCHEMA_SUBENTRY =
      AttributeDescription.create(CoreSchema.getSubschemaSubentryAttributeType());

  private static final AttributeDescription ATTR_SUPPORTED_AUTH_PASSWORD_SCHEMES =
      AttributeDescription.create(CoreSchema.getSupportedAuthPasswordSchemesAttributeType());

  private static final AttributeDescription ATTR_SUPPORTED_CONTROL =
      AttributeDescription.create(CoreSchema.getSupportedControlAttributeType());

  private static final AttributeDescription ATTR_SUPPORTED_EXTENSION =
      AttributeDescription.create(CoreSchema.getSupportedExtensionAttributeType());

  private static final AttributeDescription ATTR_SUPPORTED_FEATURE =
      AttributeDescription.create(CoreSchema.getSupportedFeaturesAttributeType());

  private static final AttributeDescription ATTR_SUPPORTED_LDAP_VERSION =
      AttributeDescription.create(CoreSchema.getSupportedLDAPVersionAttributeType());

  private static final AttributeDescription ATTR_SUPPORTED_SASL_MECHANISMS =
      AttributeDescription.create(CoreSchema.getSupportedSASLMechanismsAttributeType());

  private static final AttributeDescription ATTR_VENDOR_NAME =
      AttributeDescription.create(CoreSchema.getVendorNameAttributeType());

  private static final AttributeDescription ATTR_VENDOR_VERSION =
      AttributeDescription.create(CoreSchema.getVendorNameAttributeType());

  private static final AttributeDescription ATTR_FULL_VENDOR_VERSION =
      AttributeDescription.create(CoreSchema.getFullVendorVersionAttributeType());

  private static final SearchRequest SEARCH_REQUEST =
      Requests.newSearchRequest(
          DN.rootDN(),
          SearchScope.BASE_OBJECT,
          Filter.objectClassPresent(),
          ATTR_ALT_SERVER.toString(),
          ATTR_NAMING_CONTEXTS.toString(),
          ATTR_SUPPORTED_CONTROL.toString(),
          ATTR_SUPPORTED_EXTENSION.toString(),
          ATTR_SUPPORTED_FEATURE.toString(),
          ATTR_SUPPORTED_LDAP_VERSION.toString(),
          ATTR_SUPPORTED_SASL_MECHANISMS.toString(),
          ATTR_FULL_VENDOR_VERSION.toString(),
          ATTR_VENDOR_NAME.toString(),
          ATTR_VENDOR_VERSION.toString(),
          ATTR_SUPPORTED_AUTH_PASSWORD_SCHEMES.toString(),
          ATTR_SUBSCHEMA_SUBENTRY.toString(),
          "*");

  /**
   * Asynchronously reads the Root DSE from the Directory Server using the provided connection.
   *
   * <p>If the Root DSE is not returned by the Directory Server then the request will fail with an
   * {@link EntryNotFoundException}. More specifically, the returned promise will never return
   * {@code null}.
   *
   * @param connection A connection to the Directory Server whose Root DSE is to be read.
   * @param handler A result handler which can be used to asynchronously process the operation
   *     result when it is received, may be {@code null}.
   * @return A promise representing the result of the operation.
   * @throws UnsupportedOperationException If the connection does not support search operations.
   * @throws IllegalStateException If the connection has already been closed, i.e. if {@code
   *     isClosed() == true}.
   * @throws NullPointerException If the {@code connection} was {@code null}.
   */
  public static LdapPromise<RootDSE> readRootDSEAsync(
      final Connection connection, final ResultHandler<? super RootDSE> handler) {
    return connection
        .searchSingleEntryAsync(SEARCH_REQUEST)
        .then(
            new Function<SearchResultEntry, RootDSE, LdapException>() {
              @Override
              public RootDSE apply(SearchResultEntry result) {
                return valueOf(result);
              }
            });
  }

  /**
   * Reads the Root DSE from the Directory Server using the provided connection.
   *
   * <p>If the Root DSE is not returned by the Directory Server then the request will fail with an
   * {@link EntryNotFoundException}. More specifically, this method will never return {@code null}.
   *
   * @param connection A connection to the Directory Server whose Root DSE is to be read.
   * @return The Directory Server's Root DSE.
   * @throws LdapException If the result code indicates that the request failed for some reason.
   * @throws UnsupportedOperationException If the connection does not support search operations.
   * @throws IllegalStateException If the connection has already been closed, i.e. if {@code
   *     isClosed() == true}.
   * @throws NullPointerException If the {@code connection} was {@code null}.
   */
  public static RootDSE readRootDSE(final Connection connection) throws LdapException {
    final Entry entry = connection.searchSingleEntry(SEARCH_REQUEST);
    return valueOf(entry);
  }

  /**
   * Creates a new Root DSE instance backed by the provided entry. Modifications made to {@code
   * entry} will be reflected in the returned Root DSE. The returned Root DSE instance is
   * unmodifiable and attempts to use modify any of the returned collections will result in a {@code
   * UnsupportedOperationException}.
   *
   * @param entry The Root DSE entry.
   * @return A Root DSE instance backed by the provided entry.
   * @throws NullPointerException If {@code entry} was {@code null} .
   */
  public static RootDSE valueOf(Entry entry) {
    Reject.ifNull(entry);
    return new RootDSE(entry);
  }

  private final Entry entry;

  /** Prevent direct instantiation. */
  private RootDSE(final Entry entry) {
    this.entry = entry;
  }

  /**
   * Returns an unmodifiable list of URIs referring to alternative Directory Servers that may be
   * contacted when the Directory Server becomes unavailable.
   *
   * <p>URIs for Directory Servers implementing the LDAP protocol are written according to RFC 4516.
   * Other kinds of URIs may be provided.
   *
   * <p>If the Directory Server does not know of any other Directory Servers that could be used, the
   * returned list will be empty.
   *
   * @return An unmodifiable list of URIs referring to alternative Directory Servers, which may be
   *     empty.
   * @see <a href="http://tools.ietf.org/html/rfc4516">RFC 4516 - Lightweight Directory Access
   *     Protocol (LDAP): Uniform Resource Locator </a>
   */
  public Collection<String> getAlternativeServers() {
    return getMultiValuedAttribute(ATTR_ALT_SERVER, Functions.byteStringToString());
  }

  /**
   * Returns the entry which backs this Root DSE instance. Modifications made to the returned entry
   * will be reflected in this Root DSE.
   *
   * @return The underlying Root DSE entry.
   */
  public Entry getEntry() {
    return entry;
  }

  /**
   * Returns an unmodifiable list of DNs identifying the context prefixes of the naming contexts
   * that the Directory Server masters or shadows (in part or in whole).
   *
   * <p>If the Directory Server does not master or shadow any naming contexts, the returned list
   * will be empty.
   *
   * @return An unmodifiable list of DNs identifying the context prefixes of the naming contexts,
   *     which may be empty.
   */
  public Collection<DN> getNamingContexts() {
    return getMultiValuedAttribute(ATTR_NAMING_CONTEXTS, Functions.byteStringToDN());
  }

  /**
   * Returns a string which represents the DN of the subschema subentry holding the schema
   * controlling the Root DSE.
   *
   * <p>Clients SHOULD NOT assume that this subschema (sub)entry controls other entries held by the
   * Directory Server.
   *
   * @return The DN of the subschema subentry holding the schema controlling the Root DSE, or {@code
   *     null} if the DN is not provided.
   */
  public DN getSubschemaSubentry() {
    return getSingleValuedAttribute(ATTR_SUBSCHEMA_SUBENTRY, Functions.byteStringToDN());
  }

  /**
   * Returns an unmodifiable list of supported authentication password schemes which the Directory
   * Server supports.
   *
   * <p>If the Directory Server does not support any authentication password schemes, the returned
   * list will be empty.
   *
   * @return An unmodifiable list of supported authentication password schemes, which may be empty.
   * @see <a href="http://tools.ietf.org/html/rfc3112">RFC 3112 - LDAP Authentication Password
   *     Schema </a>
   */
  public Collection<String> getSupportedAuthenticationPasswordSchemes() {
    return getMultiValuedAttribute(
        ATTR_SUPPORTED_AUTH_PASSWORD_SCHEMES, Functions.byteStringToString());
  }

  /**
   * Returns an unmodifiable list of object identifiers identifying the request controls that the
   * Directory Server supports.
   *
   * <p>If the Directory Server does not support any request controls, the returned list will be
   * empty. Object identifiers identifying response controls may not be listed.
   *
   * @return An unmodifiable list of object identifiers identifying the request controls, which may
   *     be empty.
   */
  public Collection<String> getSupportedControls() {
    return getMultiValuedAttribute(ATTR_SUPPORTED_CONTROL, Functions.byteStringToString());
  }

  /**
   * Returns an unmodifiable list of object identifiers identifying the extended operations that the
   * Directory Server supports.
   *
   * <p>If the Directory Server does not support any extended operations, the returned list will be
   * empty.
   *
   * <p>An extended operation generally consists of an extended request and an extended response but
   * may also include other protocol data units (such as intermediate responses). The object
   * identifier assigned to the extended request is used to identify the extended operation. Other
   * object identifiers used in the extended operation may not be listed as values of this
   * attribute.
   *
   * @return An unmodifiable list of object identifiers identifying the extended operations, which
   *     may be empty.
   */
  public Collection<String> getSupportedExtendedOperations() {
    return getMultiValuedAttribute(ATTR_SUPPORTED_EXTENSION, Functions.byteStringToString());
  }

  /**
   * Returns an unmodifiable list of object identifiers identifying elective features that the
   * Directory Server supports.
   *
   * <p>If the server does not support any discoverable elective features, the returned list will be
   * empty.
   *
   * @return An unmodifiable list of object identifiers identifying the elective features, which may
   *     be empty.
   */
  public Collection<String> getSupportedFeatures() {
    return getMultiValuedAttribute(ATTR_SUPPORTED_FEATURE, Functions.byteStringToString());
  }

  /**
   * Returns an unmodifiable list of the versions of LDAP that the Directory Server supports.
   *
   * @return An unmodifiable list of the versions.
   */
  public Collection<Integer> getSupportedLDAPVersions() {
    return getMultiValuedAttribute(ATTR_SUPPORTED_LDAP_VERSION, Functions.byteStringToInteger());
  }

  /**
   * Returns an unmodifiable list of the SASL mechanisms that the Directory Server recognizes and/or
   * supports.
   *
   * <p>The contents of the returned list may depend on the current session state and may be empty
   * if the Directory Server does not support any SASL mechanisms.
   *
   * @return An unmodifiable list of the SASL mechanisms, which may be empty.
   * @see <a href="http://tools.ietf.org/html/rfc4513">RFC 4513 - Lightweight Directory Access
   *     Protocol (LDAP): Authentication Methods and Security Mechanisms </a>
   * @see <a href="http://tools.ietf.org/html/rfc4422">RFC 4422 - Simple Authentication and Security
   *     Layer (SASL) </a>
   */
  public Collection<String> getSupportedSASLMechanisms() {
    return getMultiValuedAttribute(ATTR_SUPPORTED_SASL_MECHANISMS, Functions.byteStringToString());
  }

  /**
   * Returns a string which represents the name of the Directory Server implementer.
   *
   * @return The name of the Directory Server implementer, or {@code null} if the vendor name is not
   *     provided.
   * @see <a href="http://tools.ietf.org/html/rfc3045">RFC 3045 - Storing Vendor Information in the
   *     LDAP Root DSE </a>
   */
  public String getVendorName() {
    return getSingleValuedAttribute(ATTR_VENDOR_NAME, Functions.byteStringToString());
  }

  /**
   * Returns a string which represents the version of the Directory Server implementation.
   *
   * <p>Note that this value is typically a release value comprised of a string and/or a string of
   * numbers used by the developer of the LDAP server product. The returned string will be unique
   * between two versions of the Directory Server, but there are no other syntactic restrictions on
   * the value or the way it is formatted.
   *
   * @return The version of the Directory Server implementation, or {@code null} if the vendor
   *     version is not provided.
   * @see <a href="http://tools.ietf.org/html/rfc3045">RFC 3045 - Storing Vendor Information in the
   *     LDAP Root DSE </a>
   */
  public String getVendorVersion() {
    return getSingleValuedAttribute(ATTR_VENDOR_VERSION, Functions.byteStringToString());
  }

  /**
   * Returns a string which represents the full version of the Directory Server implementation.
   *
   * @return The full version of the Directory Server implementation, or {@code null} if the vendor
   *     version is not provided.
   */
  public String getFullVendorVersion() {
    return getSingleValuedAttribute(ATTR_FULL_VENDOR_VERSION, Functions.byteStringToString());
  }

  private <N> Collection<N> getMultiValuedAttribute(
      final AttributeDescription attributeDescription,
      final Function<ByteString, N, NeverThrowsException> function) {
    // The returned collection is unmodifiable because we may need to
    // return an empty collection if the attribute does not exist in the
    // underlying entry. If a value is then added to the returned empty
    // collection it would require that an attribute is created in the
    // underlying entry in order to maintain consistency.
    final Attribute attr = entry.getAttribute(attributeDescription);
    if (attr != null) {
      return Collections.unmodifiableCollection(
          Collections2.transformedCollection(attr, function, Functions.objectToByteString()));
    } else {
      return Collections.emptySet();
    }
  }

  private <N> N getSingleValuedAttribute(
      final AttributeDescription attributeDescription,
      final Function<ByteString, N, NeverThrowsException> function) {
    final Attribute attr = entry.getAttribute(attributeDescription);
    if (attr == null || attr.isEmpty()) {
      return null;
    } else {
      return function.apply(attr.firstValue());
    }
  }
}
  AttributeEditPage(
      final AttributeDescription attribute,
      final NewFeatureTypePage previousPage,
      final boolean newAttribute) {
    this.previousPage = previousPage;
    this.newAttribute = newAttribute;
    this.attribute = attribute;
    this.size = String.valueOf(attribute.getSize());

    final Form form = new Form("form", new CompoundPropertyModel(attribute));
    form.setOutputMarkupId(true);
    add(form);

    form.add(nameField = new TextField("name"));
    DropDownChoice binding =
        new DropDownChoice("binding", AttributeDescription.BINDINGS, new BindingChoiceRenderer());
    binding.add(
        new AjaxFormSubmitBehavior("onchange") {

          @Override
          protected void onError(AjaxRequestTarget target) {
            updateVisibility(target);
          }

          private void updateVisibility(AjaxRequestTarget target) {
            sizeContainer.setVisible(String.class.equals(attribute.getBinding()));
            crsContainer.setVisible(
                attribute.getBinding() != null
                    && Geometry.class.isAssignableFrom(attribute.getBinding()));

            target.addComponent(getFeedbackPanel());
            target.addComponent(form);
          }

          @Override
          protected void onSubmit(AjaxRequestTarget target) {
            updateVisibility(target);
          }
        });
    form.add(binding);
    form.add(new CheckBox("nullable"));

    sizeContainer = new WebMarkupContainer("sizeContainer");
    sizeContainer.setOutputMarkupId(true);
    form.add(sizeContainer);
    sizeContainer.add(sizeField = new TextField("size", new PropertyModel(this, "size")));
    sizeContainer.setVisible(String.class.equals(attribute.getBinding()));

    crsContainer = new WebMarkupContainer("crsContainer");
    crsContainer.setOutputMarkupId(true);
    form.add(crsContainer);
    crsContainer.add(crsField = new CRSPanel("crs"));
    crsContainer.setVisible(
        attribute.getBinding() != null && Geometry.class.isAssignableFrom(attribute.getBinding()));

    SubmitLink submit =
        new SubmitLink("save") {
          @Override
          public void onSubmit() {
            if (validate()) {
              if (newAttribute) {
                previousPage.attributesProvider.addNewAttribute(attribute);
              }
              setResponsePage(previousPage);
            }
          }
        };
    form.setDefaultButton(submit);
    form.add(submit);
    form.add(
        new Link("cancel") {

          @Override
          public void onClick() {
            setResponsePage(previousPage);
          }
        });
  }
 public Object getDisplayValue(Object object) {
   return AttributeDescription.getLocalizedName((Class) object);
 }