001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2006-2008 Sun Microsystems, Inc. 025 * Portions Copyright 2014-2015 ForgeRock AS 026 */ 027package org.opends.server.controls; 028import org.forgerock.i18n.LocalizableMessage; 029 030 031import org.forgerock.opendj.io.*; 032import org.opends.server.protocols.ldap.*; 033import org.opends.server.protocols.ldap.LDAPReader; 034import org.opends.server.types.*; 035import org.forgerock.opendj.ldap.ResultCode; 036import org.forgerock.opendj.ldap.ByteString; 037import org.forgerock.i18n.slf4j.LocalizedLogger; 038import static org.opends.messages.ProtocolMessages.*; 039import static org.opends.server.util.ServerConstants.*; 040 041import java.io.IOException; 042 043 044/** 045 * This class implements the post-read response control as defined in RFC 4527. 046 * This control holds the search result entry representing the state of the 047 * entry immediately before an add, modify, or modify DN operation. 048 */ 049public class LDAPPostReadResponseControl 050 extends Control 051{ 052 /** 053 * ControlDecoder implementation to decode this control from a ByteString. 054 */ 055 private static final class Decoder 056 implements ControlDecoder<LDAPPostReadResponseControl> 057 { 058 /** {@inheritDoc} */ 059 public LDAPPostReadResponseControl decode(boolean isCritical, 060 ByteString value) 061 throws DirectoryException 062 { 063 if (value == null) 064 { 065 LocalizableMessage message = ERR_POSTREADRESP_NO_CONTROL_VALUE.get(); 066 throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message); 067 } 068 069 070 ASN1Reader reader = ASN1.getReader(value); 071 SearchResultEntry searchEntry; 072 try 073 { 074 SearchResultEntryProtocolOp searchResultEntryProtocolOp = 075 LDAPReader.readSearchEntry(reader); 076 searchEntry = searchResultEntryProtocolOp.toSearchResultEntry(); 077 } 078 catch (LDAPException le) 079 { 080 logger.traceException(le); 081 082 LocalizableMessage message = 083 ERR_POSTREADRESP_CANNOT_DECODE_VALUE.get(le.getMessage()); 084 throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, 085 le); 086 } 087 088 return new LDAPPostReadResponseControl(isCritical, searchEntry); 089 } 090 091 public String getOID() 092 { 093 return OID_LDAP_READENTRY_POSTREAD; 094 } 095 096 } 097 098 /** 099 * The Control Decoder that can be used to decode this control. 100 */ 101 public static final ControlDecoder<LDAPPostReadResponseControl> DECODER = 102 new Decoder(); 103 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 104 105 106 107 108 /** The search result entry to include in the response control. */ 109 private SearchResultEntry searchEntry; 110 111 112 113 /** 114 * Creates a new instance of this LDAP post-read response control with the 115 * provided information. 116 * 117 * @param searchEntry The search result entry to include in the response 118 * control. 119 */ 120 public LDAPPostReadResponseControl(SearchResultEntry searchEntry) 121 { 122 this(false, searchEntry); 123 } 124 125 126 127 /** 128 * Creates a new instance of this LDAP post-read response control with the 129 * provided information. 130 * 131 * @param isCritical Indicates whether support for this control should be 132 * considered a critical part of the server processing. 133 * @param searchEntry The search result entry to include in the response 134 * control. 135 */ 136 public LDAPPostReadResponseControl(boolean isCritical, 137 SearchResultEntry searchEntry) 138 { 139 super(OID_LDAP_READENTRY_POSTREAD, isCritical); 140 141 142 this.searchEntry = searchEntry; 143 } 144 145 /** 146 * Writes this control's value to an ASN.1 writer. The value (if any) must be 147 * written as an ASN1OctetString. 148 * 149 * @param writer The ASN.1 output stream to write to. 150 * @throws IOException If a problem occurs while writing to the stream. 151 */ 152 @Override 153 public void writeValue(ASN1Writer writer) throws IOException { 154 writer.writeStartSequence(ASN1.UNIVERSAL_OCTET_STRING_TYPE); 155 156 SearchResultEntryProtocolOp protocolOp = 157 new SearchResultEntryProtocolOp(searchEntry); 158 protocolOp.write(writer); 159 160 writer.writeEndSequence(); 161 } 162 163 164 165 /** 166 * Retrieves the search result entry associated with this post-read response 167 * control. 168 * 169 * @return The search result entry associated with this post-read response 170 * control. 171 */ 172 public SearchResultEntry getSearchEntry() 173 { 174 return searchEntry; 175 } 176 177 178 179 /** 180 * Appends a string representation of this LDAP post-read response control to 181 * the provided buffer. 182 * 183 * @param buffer The buffer to which the information should be appended. 184 */ 185 @Override 186 public void toString(StringBuilder buffer) 187 { 188 buffer.append("LDAPPostReadResponseControl(criticality="); 189 buffer.append(isCritical()); 190 buffer.append(",entry="); 191 searchEntry.toSingleLineString(buffer); 192 buffer.append(")"); 193 } 194} 195