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