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-2015 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  /**
043   * ControlDecoder implementation to decode this control from a ByteString.
044   */
045  private static final class Decoder
046      implements ControlDecoder<LDAPPostReadResponseControl>
047  {
048    /** {@inheritDoc} */
049    public LDAPPostReadResponseControl decode(boolean isCritical,
050                                              ByteString value)
051        throws DirectoryException
052    {
053      if (value == null)
054      {
055        LocalizableMessage message = ERR_POSTREADRESP_NO_CONTROL_VALUE.get();
056        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
057      }
058
059
060      ASN1Reader reader = ASN1.getReader(value);
061      SearchResultEntry searchEntry;
062      try
063      {
064        SearchResultEntryProtocolOp searchResultEntryProtocolOp =
065            LDAPReader.readSearchEntry(reader);
066        searchEntry = searchResultEntryProtocolOp.toSearchResultEntry();
067      }
068      catch (LDAPException le)
069      {
070        logger.traceException(le);
071
072        LocalizableMessage message =
073            ERR_POSTREADRESP_CANNOT_DECODE_VALUE.get(le.getMessage());
074        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message,
075            le);
076      }
077
078      return new LDAPPostReadResponseControl(isCritical, searchEntry);
079    }
080
081    public String getOID()
082    {
083      return OID_LDAP_READENTRY_POSTREAD;
084    }
085
086  }
087
088  /**
089   * The Control Decoder that can be used to decode this control.
090   */
091  public static final ControlDecoder<LDAPPostReadResponseControl> DECODER =
092    new Decoder();
093  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
094
095
096
097
098  /** The search result entry to include in the response control. */
099  private SearchResultEntry searchEntry;
100
101
102
103  /**
104   * Creates a new instance of this LDAP post-read response control with the
105   * provided information.
106   *
107   * @param  searchEntry  The search result entry to include in the response
108   *                      control.
109   */
110  public LDAPPostReadResponseControl(SearchResultEntry searchEntry)
111  {
112    this(false, searchEntry);
113  }
114
115
116
117  /**
118   * Creates a new instance of this LDAP post-read response control with the
119   * provided information.
120   *
121   * @param  isCritical    Indicates whether support for this control should be
122   *                       considered a critical part of the server processing.
123   * @param  searchEntry   The search result entry to include in the response
124   *                       control.
125   */
126  public LDAPPostReadResponseControl(boolean isCritical,
127                                     SearchResultEntry searchEntry)
128  {
129    super(OID_LDAP_READENTRY_POSTREAD, isCritical);
130
131
132    this.searchEntry = searchEntry;
133  }
134
135  /**
136   * Writes this control's value to an ASN.1 writer. The value (if any) must be
137   * written as an ASN1OctetString.
138   *
139   * @param writer The ASN.1 output stream to write to.
140   * @throws IOException If a problem occurs while writing to the stream.
141   */
142  @Override
143  public void writeValue(ASN1Writer writer) throws IOException {
144    writer.writeStartSequence(ASN1.UNIVERSAL_OCTET_STRING_TYPE);
145
146    SearchResultEntryProtocolOp protocolOp =
147        new SearchResultEntryProtocolOp(searchEntry);
148    protocolOp.write(writer);
149
150    writer.writeEndSequence();
151  }
152
153
154
155  /**
156   * Retrieves the search result entry associated with this post-read response
157   * control.
158   *
159   * @return  The search result entry associated with this post-read response
160   *          control.
161   */
162  public SearchResultEntry getSearchEntry()
163  {
164    return searchEntry;
165  }
166
167
168
169  /**
170   * Appends a string representation of this LDAP post-read response control to
171   * the provided buffer.
172   *
173   * @param  buffer  The buffer to which the information should be appended.
174   */
175  @Override
176  public void toString(StringBuilder buffer)
177  {
178    buffer.append("LDAPPostReadResponseControl(criticality=");
179    buffer.append(isCritical());
180    buffer.append(",entry=");
181    searchEntry.toSingleLineString(buffer);
182    buffer.append(")");
183  }
184}
185