/**
   * Modifies a record in the Database Server using the provided modify request.
   *
   * @param request The modify request.
   * @return The result of the operation.
   * @throws ErrorResultException If the result code indicates that the request failed for some
   *     reason.
   * @throws SQLException If the SQL query has an invalid format.
   * @throws NullPointerException If {@code request} was {@code null}, or if a corresponding mapping
   *     value could not be found in the mapping component.
   */
  @Override
  public Result modify(final ModifyRequest request) {
    Result r;
    try {
      // Split up the DN the of the request.
      final DN DN = request.getName();
      final RDN rDN = DN.rdn();
      final String filterAttributeName = rDN.getFirstAVA().getAttributeType().getNameOrOID();
      final String filterAttributeValue = rDN.getFirstAVA().getAttributeValue().toString();
      final RDN OU = DN.parent(1).rdn();
      final String OUName = OU.getFirstAVA().getAttributeValue().toString();
      final String baseDN = DN.parent(2).toString();

      // Search mapping for the corresponding table and column names.
      final String tableName = jdbcm.getTableNameFromMapping(baseDN, OUName);

      if (tableName == null)
        throw new NullPointerException(
            "JDBC Error: Could not find matching table name for OU: '"
                + OUName
                + "' in DN: '"
                + baseDN
                + "'. Please check if mapping was succesful.");
      final String columnName =
          jdbcm.getColumnNameFromMapping(tableName, baseDN, OUName, filterAttributeName);

      if (columnName == null)
        throw new NullPointerException(
            "JDBC Error: Could not find matching column name for attribute: '"
                + filterAttributeName
                + "'. Please check if mapping was succesful.");

      // Get attribute and modificationtype for each modification.
      // Search mapping for the corresponding column name for the modification attribute.
      final List<Modification> modificationList = request.getModifications();
      final ListIterator<Modification> listIter = modificationList.listIterator();
      String modificationString = "";

      while (listIter.hasNext()) {
        final Modification modification = listIter.next();
        final ModificationType modificationType = modification.getModificationType();
        final Attribute modificationAttribute = modification.getAttribute();
        final String modificationAttributeName =
            modificationAttribute.getAttributeDescription().toString();
        final String modificationColumnName =
            jdbcm.getColumnNameFromMapping(tableName, baseDN, OUName, modificationAttributeName);

        if (modificationColumnName == null)
          throw new NullPointerException(
              "JDBC Error: Could not find matching column name for attribute: '"
                  + modificationAttributeName
                  + "'. Please check if mapping was succesful.");
        String modificationAttributeValue = "";

        if (modificationType == ModificationType.ADD) {
          final Iterator<ByteString> iter = modificationAttribute.iterator();

          int counter = 0;
          while (iter.hasNext()) {
            if (counter > 0) modificationAttributeValue = modificationAttributeValue.concat(", ");
            modificationAttributeValue = modificationAttributeValue.concat(iter.next().toString());
            counter++;
          }
          final Object classType = jdbcm.getTableColumnDataType(tableName, modificationColumnName);

          if (classType == Integer.class)
            modificationAttributeValue =
                "(CASE WHEN ("
                    + modificationColumnName
                    + " = 0) THEN ' "
                    + modificationAttributeValue
                    + "' ELSE concat("
                    + modificationColumnName
                    + ", ', "
                    + modificationAttributeValue
                    + "') END)";
          else
            modificationAttributeValue =
                "(CASE WHEN ("
                    + modificationColumnName
                    + " = 'Default Value') THEN ' "
                    + modificationAttributeValue
                    + "' ELSE concat("
                    + modificationColumnName
                    + ", ', "
                    + modificationAttributeValue
                    + "') END)";
        } else if (modificationType == ModificationType.REPLACE) {
          final Iterator<ByteString> iter = modificationAttribute.iterator();

          while (iter.hasNext()) {
            modificationAttributeValue = "'" + iter.next().toString() + "'";
          }
        } else {
          final boolean nullable = jdbcm.getTableColumnNullable(tableName, modificationColumnName);

          if (nullable == false)
            throw new SQLException("Cannot delete data from not-nullable column.");
          final Object classType = jdbcm.getTableColumnDataType(tableName, modificationColumnName);

          if (classType == Integer.class)
            modificationAttributeValue = "'" + Integer.toString(0) + "'";
          else modificationAttributeValue = "'Default Value'";
        }
        modificationString =
            modificationString.concat(
                modificationColumnName + "=" + modificationAttributeValue + ", ");
      }
      modificationString = modificationString.substring(0, modificationString.length() - 2);

      // Build the SQL query.
      final Statement st = connection.createStatement();
      final String sql =
          "UPDATE "
              + tableName
              + " SET "
              + modificationString
              + " WHERE "
              + columnName
              + "='"
              + filterAttributeValue
              + "'";
      st.executeUpdate(sql);
      r = Responses.newResult(ResultCode.SUCCESS);
    } catch (SQLException e) {
      System.out.println(e.toString());
      r = Responses.newResult(ResultCode.OPERATIONS_ERROR);
      r.setCause(e);
    } catch (NullPointerException e) {
      System.out.println(e.toString());
      r = Responses.newCompareResult(ResultCode.OPERATIONS_ERROR);
      r.setCause(e);
    }
    return r;
  }
示例#2
0
  /**
   * Updates the config file during the upgrade process.
   *
   * @param configPath The original path to the file.
   * @param filter The filter to select entries. Only useful for modify change type.
   * @param changeType The change type which must be applied to ldif lines.
   * @param ldifLines The change record ldif lines. For ADD change type, the first line must be the
   *     dn. For DELETE change type, the first and only line must be the dn.
   * @throws IOException If an Exception occurs during the input output methods.
   * @return The changes number that have occurred.
   */
  static int updateConfigFile(
      final String configPath,
      final Filter filter,
      final ChangeOperationType changeType,
      final String... ldifLines)
      throws IOException {
    final File original = new File(configPath);
    final File copyConfig = File.createTempFile("copyConfig", ".tmp", original.getParentFile());

    int changeCount = 0;
    LDIFEntryReader entryReader = null;
    LDIFEntryWriter writer = null;
    try {
      final Schema schema = getUpgradeSchema();
      entryReader = new LDIFEntryReader(new FileInputStream(configPath)).setSchema(schema);

      writer = new LDIFEntryWriter(new FileOutputStream(copyConfig));
      writer.setWrapColumn(80);

      // Writes the header on the new file.
      writer.writeComment(INFO_CONFIG_FILE_HEADER.get());
      writer.setWrapColumn(0);

      boolean entryAlreadyExist = false;
      DN ldifDN = null;
      if (filter == null && (changeType == ADD || changeType == DELETE)) {
        // The first line should start with dn:
        ldifDN = DN.valueOf(ldifLines[0].replaceFirst("dn: ", ""));
      }
      final Filter f = filter != null ? filter : Filter.alwaysFalse();
      final Matcher matcher = f.matcher(schema);
      while (entryReader.hasNext()) {
        Entry entry = entryReader.readEntry();
        final DN entryDN = entry.getName();
        // Searching for the related entries
        if (changeType == MODIFY && matcher.matches(entry) == ConditionResult.TRUE) {
          try {
            final ModifyRequest mr =
                Requests.newModifyRequest(readLDIFLines(entryDN, changeType, ldifLines));
            entry = Entries.modifyEntryPermissive(entry, mr.getModifications());
            changeCount++;
            logger.debug(
                LocalizableMessage.raw("The following entry has been modified : %s", entryDN));
          } catch (Exception ex) {
            logger.error(LocalizableMessage.raw(ex.getMessage()));
          }
        }

        if (entryDN.equals(ldifDN)) {
          logger.debug(LocalizableMessage.raw("Entry %s found", entryDN));
          entryAlreadyExist = true;

          if (changeType == DELETE) {
            entry = null;
            changeCount++;
            logger.debug(
                LocalizableMessage.raw("The following entry has been deleted : %s", entryDN));
          }
        }

        if (entry != null) {
          writer.writeEntry(entry);
        }
      }

      if (changeType == ADD && !entryAlreadyExist) {
        final AddRequest ar = Requests.newAddRequest(ldifLines);
        writer.writeEntry(ar);
        logger.debug(
            LocalizableMessage.raw(
                "Entry successfully added %s in %s", ldifDN, original.getAbsolutePath()));
        changeCount++;
      }
    } catch (Exception ex) {
      throw new IOException(ex.getMessage());
    } finally {
      // The reader and writer must be close before renaming files.
      // Otherwise it causes exceptions under windows OS.
      StaticUtils.close(entryReader, writer);
    }

    try {
      // Renaming the file, overwriting previous one.
      rename(copyConfig, new File(configPath));
    } catch (IOException e) {
      logger.error(LocalizableMessage.raw(e.getMessage()));
      deleteRecursively(original);
      throw e;
    }

    return changeCount;
  }