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