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.List;
023
024import org.forgerock.i18n.LocalizableMessage;
025import org.forgerock.opendj.ldap.DecodeException;
026import org.opends.server.protocols.ldap.CompareRequestProtocolOp;
027import org.opends.server.protocols.ldap.CompareResponseProtocolOp;
028import org.opends.server.protocols.ldap.LDAPMessage;
029import org.opends.server.protocols.ldap.ProtocolOp;
030import org.opends.server.tools.LDAPConnection;
031import org.forgerock.opendj.ldap.ByteString;
032import org.opends.server.types.LDAPException;
033
034
035
036/**
037 * This class provides the functionality for the performing an
038 * LDAP COMPARE operation based on the specified DSML request.
039 */
040public class DSMLCompareOperation
041{
042  private LDAPConnection connection;
043
044  /**
045   * Create an instance with the specified LDAP connection.
046   *
047   * @param connection    The LDAP connection to send the request on.
048   */
049  public DSMLCompareOperation(LDAPConnection connection)
050  {
051    this.connection = connection;
052  }
053
054  /**
055   * Perform the LDAP COMPARE operation and send the result back to the
056   * client.
057   *
058   * @param  objFactory      The object factory for this operation.
059   * @param  compareRequest  The compare request for this operation.
060   * @param  controls        Any required controls (e.g. for proxy authz).
061   *
062   * @return  The result of the compare operation.
063   *
064   * @throws  IOException  If an I/O problem occurs.
065   *
066   * @throws  LDAPException  If an error occurs while interacting with an LDAP
067   *                         element.
068   *
069   * @throws  DecodeException  If an error occurs while interacting with an ASN.1
070   *                         element.
071   */
072  public LDAPResult doOperation(ObjectFactory objFactory,
073        CompareRequest compareRequest,
074        List<org.opends.server.types.Control> controls)
075    throws IOException, LDAPException, DecodeException
076  {
077    LDAPResult compareResponse = objFactory.createLDAPResult();
078    compareResponse.setRequestID(compareRequest.getRequestID());
079
080    // Read the attribute name and value for the compare request.
081    AttributeValueAssertion attrValAssertion = compareRequest.getAssertion();
082    String attrName = attrValAssertion.getName();
083    Object assertion = attrValAssertion.getValue();
084    ByteString attrValue = ByteStringUtility.convertValue(assertion);
085    ByteString dnStr = ByteString.valueOfUtf8(compareRequest.getDn());
086
087    // Create and send the LDAP compare request to the server.
088    ProtocolOp op = new CompareRequestProtocolOp(dnStr, attrName, attrValue);
089    LDAPMessage msg = new LDAPMessage(DSMLServlet.nextMessageID(), op,
090        controls);
091    connection.getLDAPWriter().writeMessage(msg);
092
093    // Read and decode the LDAP response from the server.
094    LDAPMessage responseMessage = connection.getLDAPReader().readMessage();
095
096    CompareResponseProtocolOp compareOp =
097          responseMessage.getCompareResponseProtocolOp();
098    int resultCode = compareOp.getResultCode();
099    LocalizableMessage errorMessage = compareOp.getErrorMessage();
100
101    // Set the response code and error message for the DSML response.
102    compareResponse.setErrorMessage(
103            errorMessage != null ? errorMessage.toString() : null);
104    ResultCode code = ResultCodeFactory.create(objFactory, resultCode);
105    compareResponse.setResultCode(code);
106
107    if(compareOp.getMatchedDN() != null)
108    {
109      compareResponse.setMatchedDN(compareOp.getMatchedDN().toString());
110    }
111
112    return compareResponse;
113  }
114
115}
116