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
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.controls;
028 import org.opends.messages.Message;
029
030
031
032 import org.opends.server.protocols.asn1.ASN1Element;
033 import org.opends.server.protocols.asn1.ASN1Exception;
034 import org.opends.server.protocols.asn1.ASN1OctetString;
035 import org.opends.server.protocols.ldap.LDAPResultCode;
036 import org.opends.server.protocols.ldap.SearchResultEntryProtocolOp;
037 import org.opends.server.types.Control;
038 import org.opends.server.types.SearchResultEntry;
039 import org.opends.server.types.DebugLogLevel;
040 import org.opends.server.types.LDAPException;
041
042 import static org.opends.server.loggers.debug.DebugLogger.*;
043 import org.opends.server.loggers.debug.DebugTracer;
044 import static org.opends.messages.ProtocolMessages.*;
045 import static org.opends.server.util.ServerConstants.*;
046
047
048
049 /**
050 * This class implements the pre-read response control as defined in RFC 4527.
051 * This control holds the search result entry representing the state of the
052 * entry immediately before a modify, delete, or modify DN operation.
053 */
054 public class LDAPPreReadResponseControl
055 extends Control
056 {
057 /**
058 * The tracer object for the debug logger.
059 */
060 private static final DebugTracer TRACER = getTracer();
061
062
063
064
065 // The search result entry to include in the response control.
066 private SearchResultEntry searchEntry;
067
068
069
070 /**
071 * Creates a new instance of this LDAP pre-read response control with the
072 * provided information.
073 *
074 * @param searchEntry The search result entry to include in the response
075 * control.
076 */
077 public LDAPPreReadResponseControl(SearchResultEntry searchEntry)
078 {
079 super(OID_LDAP_READENTRY_PREREAD, false,
080 encodeEntry(searchEntry));
081
082
083 this.searchEntry = searchEntry;
084 }
085
086
087
088 /**
089 * Creates a new instance of this LDAP pre-read response control with the
090 * provided information.
091 *
092 * @param oid The OID to use for this control.
093 * @param isCritical Indicates whether support for this control should be
094 * considered a critical part of the server processing.
095 * @param searchEntry The search result entry to include in the response
096 * control.
097 */
098 public LDAPPreReadResponseControl(String oid, boolean isCritical,
099 SearchResultEntry searchEntry)
100 {
101 super(oid, isCritical, encodeEntry(searchEntry));
102
103
104 this.searchEntry = searchEntry;
105 }
106
107
108
109 /**
110 * Creates a new instance of this LDAP pre-read response control with the
111 * provided information.
112 *
113 * @param oid The OID to use for this control.
114 * @param isCritical Indicates whether support for this control should be
115 * considered a critical part of the server processing.
116 * @param searchEntry The search result entry to include in the response
117 * control.
118 * @param encodedValue The pre-encoded value for this control.
119 */
120 private LDAPPreReadResponseControl(String oid, boolean isCritical,
121 SearchResultEntry searchEntry,
122 ASN1OctetString encodedValue)
123 {
124 super(oid, isCritical, encodedValue);
125
126
127 this.searchEntry = searchEntry;
128 }
129
130
131
132 /**
133 * Creates a new LDAP pre-read response control from the contents of the
134 * provided control.
135 *
136 * @param control The generic control containing the information to use to
137 * create this LDAP pre-read response control.
138 *
139 * @return The LDAP pre-read response control decoded from the provided
140 * control.
141 *
142 * @throws LDAPException If this control cannot be decoded as a valid LDAP
143 * pre-read response control.
144 */
145 public static LDAPPreReadResponseControl decodeControl(Control control)
146 throws LDAPException
147 {
148 if (! control.hasValue())
149 {
150 Message message = ERR_PREREADRESP_NO_CONTROL_VALUE.get();
151 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
152 }
153
154
155 ASN1OctetString controlValue = control.getValue();
156 SearchResultEntry searchEntry;
157 try
158 {
159 ASN1Element element = ASN1Element.decode(controlValue.value());
160 SearchResultEntryProtocolOp searchResultEntryProtocolOp =
161 SearchResultEntryProtocolOp.decodeSearchEntry(element);
162 searchEntry = searchResultEntryProtocolOp.toSearchResultEntry();
163 }
164 catch (ASN1Exception ae)
165 {
166 if (debugEnabled())
167 {
168 TRACER.debugCaught(DebugLogLevel.ERROR, ae);
169 }
170
171 Message message =
172 ERR_PREREADRESP_CANNOT_DECODE_VALUE.get(ae.getMessage());
173 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message,
174 ae);
175 }
176 catch (LDAPException le)
177 {
178 if (debugEnabled())
179 {
180 TRACER.debugCaught(DebugLogLevel.ERROR, le);
181 }
182
183 Message message =
184 ERR_PREREADRESP_CANNOT_DECODE_VALUE.get(le.getMessage());
185 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message,
186 le);
187 }
188
189 return new LDAPPreReadResponseControl(control.getOID(),
190 control.isCritical(), searchEntry,
191 controlValue);
192 }
193
194
195
196 /**
197 * Encodes the provided search result entry for use as an attribute value.
198 *
199 * @param searchEntry The search result entry to be encoded.
200 *
201 * @return The ASN.1 octet string containing the encoded control value.
202 */
203 private static ASN1OctetString encodeEntry(SearchResultEntry searchEntry)
204 {
205 SearchResultEntryProtocolOp protocolOp =
206 new SearchResultEntryProtocolOp(searchEntry);
207 return new ASN1OctetString(protocolOp.encode().encode());
208 }
209
210
211
212 /**
213 * Retrieves the search result entry associated with this pre-read response
214 * control.
215 *
216 * @return The search result entry associated with this pre-read response
217 * control.
218 */
219 public SearchResultEntry getSearchEntry()
220 {
221 return searchEntry;
222 }
223
224
225
226 /**
227 * Specifies the search result entry for use with this pre-read response
228 * control.
229 *
230 * @param searchEntry The search result entry for use with this pre-read
231 * response control.
232 */
233 public void setSearchEntry(SearchResultEntry searchEntry)
234 {
235 this.searchEntry = searchEntry;
236 setValue(encodeEntry(searchEntry));
237 }
238
239
240
241 /**
242 * Retrieves a string representation of this LDAP pre-read response control.
243 *
244 * @return A string representation of this LDAP pre-read response control.
245 */
246 public String toString()
247 {
248 StringBuilder buffer = new StringBuilder();
249 toString(buffer);
250 return buffer.toString();
251 }
252
253
254
255 /**
256 * Appends a string representation of this LDAP pre-read response control to
257 * the provided buffer.
258 *
259 * @param buffer The buffer to which the information should be appended.
260 */
261 public void toString(StringBuilder buffer)
262 {
263 buffer.append("LDAPPreReadResponseControl(criticality=");
264 buffer.append(isCritical());
265 buffer.append(",entry=");
266 searchEntry.toSingleLineString(buffer);
267 buffer.append(")");
268 }
269 }
270