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 2011-2015 ForgeRock AS
026 */
027package org.opends.server.controls;
028
029import static org.opends.messages.ProtocolMessages.*;
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.opendj.io.ASN1;
037import org.forgerock.opendj.io.ASN1Reader;
038import org.forgerock.opendj.io.ASN1Writer;
039import org.opends.server.replication.common.MultiDomainServerState;
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 * This class implements the control used to browse the external changelog.
047 */
048public class ExternalChangelogRequestControl
049       extends Control
050{
051  private MultiDomainServerState cookie;
052
053  /**
054   * ControlDecoder implementation to decode this control from a ByteString.
055   */
056  private static final class Decoder
057      implements ControlDecoder<ExternalChangelogRequestControl>
058  {
059    /** {@inheritDoc} */
060    public ExternalChangelogRequestControl decode(boolean isCritical,
061        ByteString value)
062    throws DirectoryException
063    {
064      MultiDomainServerState mdss;
065      if (value == null)
066      {
067        mdss = new MultiDomainServerState();
068      } else {
069
070      ASN1Reader reader = ASN1.getReader(value);
071      String mdssValue = null;
072      try
073      {
074        mdssValue = reader.readOctetStringAsString();
075        mdss = new MultiDomainServerState(mdssValue);
076      }
077      catch (Exception e)
078      {
079        try
080        {
081          mdssValue = value.toString();
082          mdss = new MultiDomainServerState(mdssValue);
083        }
084        catch (Exception e2)
085        {
086          LocalizableMessage message =
087            ERR_CANNOT_DECODE_CONTROL_VALUE.get(
088                getOID() + " x=" + value.toHexString() + " v="
089                + mdssValue , getExceptionMessage(e));
090          throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
091        }
092      }
093      }
094      return new ExternalChangelogRequestControl(isCritical, mdss);
095    }
096
097    public String getOID()
098    {
099      return OID_ECL_COOKIE_EXCHANGE_CONTROL;
100    }
101
102  }
103
104  /**
105   * The Control Decoder that can be used to decode this control.
106   */
107  public static final ControlDecoder<ExternalChangelogRequestControl> DECODER =
108    new Decoder();
109
110  /**
111   * Create a new external change log request control to contain the cookie.
112   * @param isCritical Specifies whether the control is critical.
113   * @param cookie Specifies the cookie value.
114   */
115  public ExternalChangelogRequestControl(boolean isCritical,
116      MultiDomainServerState cookie)
117  {
118    super(OID_ECL_COOKIE_EXCHANGE_CONTROL, isCritical);
119    this.cookie = cookie;
120  }
121
122  /**
123   * Returns the cookie value.
124   * @return The cookie value.
125   */
126  public MultiDomainServerState getCookie()
127  {
128    return this.cookie;
129  }
130
131  /**
132   * Dump a string representation of this object to the provided bufer.
133   * @param buffer The provided buffer.
134   */
135  public void toString(StringBuilder buffer)
136  {
137    buffer.append("ExternalChangelogRequestControl(cookie=");
138    this.cookie.toString(buffer);
139    buffer.append(")");
140  }
141
142  /**
143   * Writes this control's value to an ASN.1 writer. The value
144   * (if any) must be written as an ASN1OctetString.
145   *
146   * @param writer The ASN.1 writer to use.
147   * @throws IOException If a problem occurs while writing to the
148   *                     stream.
149   */
150  protected void writeValue(ASN1Writer writer)
151      throws IOException
152  {
153    writer.writeStartSequence(ASN1.UNIVERSAL_OCTET_STRING_TYPE);
154    writer.writeOctetString(this.cookie.toString());
155    writer.writeEndSequence();
156  }
157}
158