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.SearchResultEntryProtocolOp;
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 pre-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 a modify, delete, or modify DN operation.
038 */
039public class LDAPPreReadResponseControl
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<LDAPPreReadResponseControl>
047  {
048    /** {@inheritDoc} */
049    public LDAPPreReadResponseControl decode(boolean isCritical,
050                                             ByteString value)
051        throws DirectoryException
052    {
053     if (value == null)
054      {
055        LocalizableMessage message = ERR_PREREADRESP_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_PREREADRESP_CANNOT_DECODE_VALUE.get(le.getMessage());
074        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message,
075            le);
076      }
077
078      return new LDAPPreReadResponseControl(isCritical, searchEntry);
079    }
080
081    public String getOID()
082    {
083      return OID_LDAP_READENTRY_PREREAD;
084    }
085
086  }
087
088  /**
089   * The Control Decoder that can be used to decode this control.
090   */
091  public static final ControlDecoder<LDAPPreReadResponseControl> 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 pre-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 LDAPPreReadResponseControl(SearchResultEntry searchEntry)
111  {
112    this(false, searchEntry);
113  }
114
115
116
117  /**
118   * Creates a new instance of this LDAP pre-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 LDAPPreReadResponseControl(boolean isCritical,
127                                    SearchResultEntry searchEntry)
128  {
129    super(OID_LDAP_READENTRY_PREREAD, isCritical);
130
131
132    this.searchEntry = searchEntry;
133  }
134
135
136
137  /**
138   * Writes this control's value to an ASN.1 writer. The value (if any) must be
139   * written as an ASN1OctetString.
140   *
141   * @param writer The ASN.1 output stream to write to.
142   * @throws IOException If a problem occurs while writing to the stream.
143   */
144  @Override
145  public void writeValue(ASN1Writer writer) throws IOException {
146    writer.writeStartSequence(ASN1.UNIVERSAL_OCTET_STRING_TYPE);
147
148    SearchResultEntryProtocolOp protocolOp =
149        new SearchResultEntryProtocolOp(searchEntry);
150
151    protocolOp.write(writer);
152    writer.writeEndSequence();
153  }
154
155
156
157  /**
158   * Retrieves the search result entry associated with this pre-read response
159   * control.
160   *
161   * @return  The search result entry associated with this pre-read response
162   *          control.
163   */
164  public SearchResultEntry getSearchEntry()
165  {
166    return searchEntry;
167  }
168
169
170
171  /**
172   * Appends a string representation of this LDAP pre-read response control to
173   * the provided buffer.
174   *
175   * @param  buffer  The buffer to which the information should be appended.
176   */
177  @Override
178  public void toString(StringBuilder buffer)
179  {
180    buffer.append("LDAPPreReadResponseControl(criticality=");
181    buffer.append(isCritical());
182    buffer.append(",entry=");
183    searchEntry.toSingleLineString(buffer);
184    buffer.append(")");
185  }
186}
187