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