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 2014-2016 ForgeRock AS.
016 */
017package org.opends.server.controls;
018import org.forgerock.i18n.LocalizableMessage;
019
020
021import org.forgerock.opendj.io.*;
022import org.opends.server.protocols.ldap.*;
023import org.opends.server.protocols.ldap.LDAPReader;
024import org.opends.server.types.*;
025import org.forgerock.opendj.ldap.ResultCode;
026import org.forgerock.opendj.ldap.ByteString;
027import org.forgerock.i18n.slf4j.LocalizedLogger;
028import static org.opends.messages.ProtocolMessages.*;
029import static org.opends.server.util.ServerConstants.*;
030
031import java.io.IOException;
032
033
034/**
035 * This class implements the post-read response control as defined in RFC 4527.
036 * This control holds the search result entry representing the state of the
037 * entry immediately before an add, modify, or modify DN operation.
038 */
039public class LDAPPostReadResponseControl
040    extends Control
041{
042  /** ControlDecoder implementation to decode this control from a ByteString. */
043  private static final class Decoder
044      implements ControlDecoder<LDAPPostReadResponseControl>
045  {
046    @Override
047    public LDAPPostReadResponseControl decode(boolean isCritical,
048                                              ByteString value)
049        throws DirectoryException
050    {
051      if (value == null)
052      {
053        LocalizableMessage message = ERR_POSTREADRESP_NO_CONTROL_VALUE.get();
054        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
055      }
056
057
058      ASN1Reader reader = ASN1.getReader(value);
059      SearchResultEntry searchEntry;
060      try
061      {
062        SearchResultEntryProtocolOp searchResultEntryProtocolOp =
063            LDAPReader.readSearchEntry(reader);
064        searchEntry = searchResultEntryProtocolOp.toSearchResultEntry();
065      }
066      catch (LDAPException le)
067      {
068        logger.traceException(le);
069
070        LocalizableMessage message =
071            ERR_POSTREADRESP_CANNOT_DECODE_VALUE.get(le.getMessage());
072        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message,
073            le);
074      }
075
076      return new LDAPPostReadResponseControl(isCritical, searchEntry);
077    }
078
079    @Override
080    public String getOID()
081    {
082      return OID_LDAP_READENTRY_POSTREAD;
083    }
084
085  }
086
087  /** The Control Decoder that can be used to decode this control. */
088  public static final ControlDecoder<LDAPPostReadResponseControl> DECODER =
089    new Decoder();
090  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
091
092
093
094
095  /** The search result entry to include in the response control. */
096  private SearchResultEntry searchEntry;
097
098
099
100  /**
101   * Creates a new instance of this LDAP post-read response control with the
102   * provided information.
103   *
104   * @param  searchEntry  The search result entry to include in the response
105   *                      control.
106   */
107  public LDAPPostReadResponseControl(SearchResultEntry searchEntry)
108  {
109    this(false, searchEntry);
110  }
111
112
113
114  /**
115   * Creates a new instance of this LDAP post-read response control with the
116   * provided information.
117   *
118   * @param  isCritical    Indicates whether support for this control should be
119   *                       considered a critical part of the server processing.
120   * @param  searchEntry   The search result entry to include in the response
121   *                       control.
122   */
123  public LDAPPostReadResponseControl(boolean isCritical,
124                                     SearchResultEntry searchEntry)
125  {
126    super(OID_LDAP_READENTRY_POSTREAD, isCritical);
127
128
129    this.searchEntry = searchEntry;
130  }
131
132  @Override
133  public void writeValue(ASN1Writer writer) throws IOException {
134    writer.writeStartSequence(ASN1.UNIVERSAL_OCTET_STRING_TYPE);
135
136    SearchResultEntryProtocolOp protocolOp =
137        new SearchResultEntryProtocolOp(searchEntry);
138    protocolOp.write(writer);
139
140    writer.writeEndSequence();
141  }
142
143
144
145  /**
146   * Retrieves the search result entry associated with this post-read response
147   * control.
148   *
149   * @return  The search result entry associated with this post-read response
150   *          control.
151   */
152  public SearchResultEntry getSearchEntry()
153  {
154    return searchEntry;
155  }
156
157
158
159  /**
160   * Appends a string representation of this LDAP post-read response control to
161   * the provided buffer.
162   *
163   * @param  buffer  The buffer to which the information should be appended.
164   */
165  @Override
166  public void toString(StringBuilder buffer)
167  {
168    buffer.append("LDAPPostReadResponseControl(criticality=");
169    buffer.append(isCritical());
170    buffer.append(",entry=");
171    searchEntry.toSingleLineString(buffer);
172    buffer.append(")");
173  }
174}
175