/** * 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; }
/** * 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; }