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 2006-2008 Sun Microsystems, Inc.
015 * Portions Copyright 2012-2015 ForgeRock AS.
016 */
017package org.opends.dsml.protocol;
018
019
020
021import java.io.IOException;
022import java.util.ArrayList;
023import java.util.List;
024
025import org.forgerock.i18n.LocalizableMessage;
026import org.forgerock.opendj.ldap.DecodeException;
027import org.opends.server.protocols.ldap.LDAPAttribute;
028import org.opends.server.protocols.ldap.LDAPMessage;
029import org.opends.server.protocols.ldap.LDAPModification;
030import org.opends.server.protocols.ldap.ModifyRequestProtocolOp;
031import org.opends.server.protocols.ldap.ModifyResponseProtocolOp;
032import org.opends.server.protocols.ldap.ProtocolOp;
033import org.opends.server.tools.LDAPConnection;
034import org.forgerock.opendj.ldap.ByteString;
035import org.opends.server.types.LDAPException;
036import org.forgerock.opendj.ldap.ModificationType;
037import org.opends.server.types.RawModification;
038
039
040
041/**
042 * This class provides the functionality for the performing an
043 * LDAP MODIFY operation based on the specified DSML request.
044 */
045public class DSMLModifyOperation
046{
047  private LDAPConnection connection;
048
049  /**
050   * Create the instance with the specified LDAP connection.
051   *
052   * @param connection    The LDAP connection to send the request.
053   */
054  public DSMLModifyOperation(LDAPConnection connection)
055  {
056    this.connection = connection;
057  }
058
059
060  /**
061   * Perform the LDAP Modify operation and send the result back to the client.
062   *
063   * @param  objFactory     The object factory for this operation.
064   * @param  modifyRequest  The modify request for this operation.
065   * @param  controls       Any required controls (e.g. for proxy authz).
066   *
067   * @return  The result of the modify operation.
068   *
069   * @throws  IOException  If an I/O problem occurs.
070   *
071   * @throws  LDAPException  If an error occurs while interacting with an LDAP
072   *                         element.
073   *
074   * @throws  DecodeException  If an error occurs while interacting with an ASN.1
075   *                         element.
076   */
077  public LDAPResult doOperation(ObjectFactory objFactory,
078        ModifyRequest modifyRequest,
079        List<org.opends.server.types.Control> controls)
080        throws IOException, LDAPException, DecodeException
081  {
082    LDAPResult modResponse = objFactory.createLDAPResult();
083    modResponse.setRequestID(modifyRequest.getRequestID());
084
085    ArrayList<RawModification> modifications = new ArrayList<>();
086
087    // Read the modification type from the DSML request.
088    List<DsmlModification> mods = modifyRequest.getModification();
089    for(DsmlModification attr : mods)
090    {
091      String operation = attr.getOperation();
092      ModificationType type = ModificationType.ADD;
093      if(operation.equals("delete"))
094      {
095        type = ModificationType.DELETE;
096      } else if(operation.equals("replace"))
097      {
098        type = ModificationType.REPLACE;
099      }
100
101      // Read the attribute name and values.
102      String attrType = attr.getName();
103      ArrayList<ByteString> values = new ArrayList<>();
104
105      for (Object val : attr.getValue())
106      {
107        values.add(ByteStringUtility.convertValue(val));
108      }
109      LDAPAttribute ldapAttr = new LDAPAttribute(attrType, values);
110
111      LDAPModification ldapMod = new LDAPModification(type, ldapAttr);
112      modifications.add(ldapMod);
113
114    }
115
116    ByteString dnStr = ByteString.valueOfUtf8(modifyRequest.getDn());
117
118    // Create and send the LDAP request to the server.
119    ProtocolOp op = new ModifyRequestProtocolOp(dnStr, modifications);
120    LDAPMessage msg = new LDAPMessage(DSMLServlet.nextMessageID(), op,
121        controls);
122    connection.getLDAPWriter().writeMessage(msg);
123
124    // Read and parse the LDAP response from the server.
125    LDAPMessage responseMessage = connection.getLDAPReader().readMessage();
126
127    ModifyResponseProtocolOp modOp =
128         responseMessage.getModifyResponseProtocolOp();
129    int resultCode = modOp.getResultCode();
130    LocalizableMessage errorMessage = modOp.getErrorMessage();
131
132    // Set the result code and error message for the DSML response.
133    modResponse.setErrorMessage(
134            errorMessage != null ? errorMessage.toString() : null);
135    ResultCode code = ResultCodeFactory.create(objFactory, resultCode);
136    modResponse.setResultCode(code);
137
138    return modResponse;
139  }
140
141}
142