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 2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.server.controls;
028import static org.opends.messages.ProtocolMessages.ERR_ECLN_CANNOT_DECODE_VALUE;
029import static org.opends.messages.ProtocolMessages.ERR_ECLN_NO_CONTROL_VALUE;
030import static org.opends.server.util.ServerConstants.*;
031import static org.opends.server.util.StaticUtils.getExceptionMessage;
032
033import java.io.IOException;
034
035import org.forgerock.i18n.LocalizableMessage;
036import org.forgerock.i18n.slf4j.LocalizedLogger;
037import org.forgerock.opendj.io.ASN1;
038import org.forgerock.opendj.io.ASN1Reader;
039import org.forgerock.opendj.io.ASN1Writer;
040import org.forgerock.opendj.ldap.ByteString;
041import org.opends.server.types.Control;
042import org.opends.server.types.DirectoryException;
043import org.forgerock.opendj.ldap.ResultCode;
044
045
046
047/**
048 * This class implements the ECL cookie control.
049 * It may be included in entries returned in response to a search or
050 * persistent search operation.
051 */
052public class EntryChangelogNotificationControl
053       extends Control
054       {
055  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
056
057  /** The cookie value - payload of this control. */
058  private String cookie;
059
060  /**
061   * ControlDecoder implementation to decode this control from a ByteString.
062   */
063  private static final class Decoder
064  implements ControlDecoder<EntryChangelogNotificationControl>
065  {
066    /** {@inheritDoc} */
067    public EntryChangelogNotificationControl decode(
068        boolean isCritical, ByteString value)
069    throws DirectoryException
070    {
071      if (value == null)
072      {
073        LocalizableMessage message = ERR_ECLN_NO_CONTROL_VALUE.get();
074        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
075      }
076
077
078      String cookie = null;
079      ASN1Reader reader = ASN1.getReader(value);
080      try
081      {
082        reader.readStartSequence();
083        cookie = reader.readOctetStringAsString();
084      }
085      catch (Exception e)
086      {
087        logger.traceException(e);
088
089        LocalizableMessage message =
090          ERR_ECLN_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
091        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
092      }
093      return new EntryChangelogNotificationControl(isCritical, cookie);
094    }
095
096    public String getOID()
097    {
098      return OID_ECL_COOKIE_EXCHANGE_CONTROL;
099    }
100
101  }
102
103  /**
104   * The Control Decoder that can be used to decode this control.
105   */
106  public static final ControlDecoder<EntryChangelogNotificationControl>
107  DECODER = new Decoder();
108
109  /**
110   * Creates a new entry change notification control with the provided
111   * information.
112   *
113   * @param  isCritical  Indicates whether this control should be
114   *                     considered critical in processing the
115   *                     request.
116   * @param  cookie      The provided cookie value.
117   */
118  public EntryChangelogNotificationControl(boolean isCritical,
119      String cookie)
120  {
121    super(OID_ECL_COOKIE_EXCHANGE_CONTROL, isCritical);
122    this.cookie = cookie;
123  }
124
125  /**
126   * Writes this control's value to an ASN.1 writer. The value (if any)
127   * must be written as an ASN1OctetString.
128   *
129   * @param writer The ASN.1 output stream to write to.
130   * @throws IOException If a problem occurs while writing to the stream.
131   */
132  public void writeValue(ASN1Writer writer) throws IOException {
133    writer.writeStartSequence(ASN1.UNIVERSAL_OCTET_STRING_TYPE);
134    writer.writeStartSequence();
135    writer.writeOctetString(cookie);
136    writer.writeEndSequence();
137    writer.writeEndSequence();
138  }
139
140
141
142  /**
143   * Retrieves the change type for this entry change notification control.
144   *
145   * @return  The change type for this entry change notification control.
146   */
147  public String getCookie()
148  {
149    return cookie;
150  }
151
152  /**
153   * Appends a string representation of this entry change notification control
154   * to the provided buffer.
155   *
156   * @param  buffer  The buffer to which the information should be appended.
157   */
158  public void toString(StringBuilder buffer)
159  {
160    buffer.append("EntryChangelogNotificationControl(cookie=");
161    buffer.append(cookie);
162    buffer.append(")");
163  }
164}
165