![JAR search and dependency download from the Maven repository](/logo.png)
com.unboundid.ldap.sdk.controls.ContentSyncInfoIntermediateResponse Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of unboundid-ldapsdk Show documentation
Show all versions of unboundid-ldapsdk Show documentation
The UnboundID LDAP SDK for Java is a fast, comprehensive, and easy-to-use
Java API for communicating with LDAP directory servers and performing
related tasks like reading and writing LDIF, encoding and decoding data
using base64 and ASN.1 BER, and performing secure communication. This
package contains the Standard Edition of the LDAP SDK, which is a
complete, general-purpose library for communicating with LDAPv3 directory
servers.
/*
* Copyright 2010-2018 Ping Identity Corporation
* All Rights Reserved.
*/
/*
* Copyright (C) 2010-2018 Ping Identity Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (GPLv2 only)
* or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
package com.unboundid.ldap.sdk.controls;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import com.unboundid.asn1.ASN1Boolean;
import com.unboundid.asn1.ASN1Constants;
import com.unboundid.asn1.ASN1Element;
import com.unboundid.asn1.ASN1OctetString;
import com.unboundid.asn1.ASN1Sequence;
import com.unboundid.asn1.ASN1Set;
import com.unboundid.ldap.sdk.Control;
import com.unboundid.ldap.sdk.IntermediateResponse;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.util.Debug;
import com.unboundid.util.NotMutable;
import com.unboundid.util.StaticUtils;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
import com.unboundid.util.Validator;
import static com.unboundid.ldap.sdk.controls.ControlMessages.*;
/**
* This class provides an implementation of the sync info message, which is
* an intermediate response message used by the content synchronization
* operation as defined in
* RFC 4533. Directory
* servers may return this response in the course of processing a search
* request containing the content synchronization request control. See the
* documentation for the {@link ContentSyncRequestControl} class for more
* information about using the content synchronization operation.
*/
@NotMutable()
@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
public final class ContentSyncInfoIntermediateResponse
extends IntermediateResponse
{
/**
* The OID (1.3.6.1.4.1.4203.1.9.1.4) for the sync info intermediate response.
*/
public static final String SYNC_INFO_OID = "1.3.6.1.4.1.4203.1.9.1.4";
/**
* The serial version UID for this serializable class.
*/
private static final long serialVersionUID = 4464376009337157433L;
// An updated state cookie, if available.
private final ASN1OctetString cookie;
// Indicates whether the provided set of UUIDs represent entries that have
// been removed.
private final boolean refreshDeletes;
// Indicates whether the refresh phase is complete.
private final boolean refreshDone;
// The type of content synchronization information represented in this
// response.
private final ContentSyncInfoType type;
// A list of entryUUIDs for the set of entries associated with this message.
private final List entryUUIDs;
/**
* Creates a new content synchronization info intermediate response with the
* provided information.
*
* @param type The type of content synchronization information
* represented in this response.
* @param value The encoded value for the intermediate response, if
* any.
* @param cookie An updated state cookie for the synchronization
* session, if available.
* @param refreshDone Indicates whether the refresh phase of the
* synchronization session is complete.
* @param refreshDeletes Indicates whether the provided set of UUIDs
* represent entries that have been removed.
* @param entryUUIDs A list of entryUUIDs for the set of entries
* associated with this message.
* @param controls The set of controls to include in the intermediate
* response, if any.
*/
private ContentSyncInfoIntermediateResponse(final ContentSyncInfoType type,
final ASN1OctetString value, final ASN1OctetString cookie,
final boolean refreshDone, final boolean refreshDeletes,
final List entryUUIDs, final Control... controls)
{
super(SYNC_INFO_OID, value, controls);
this.type = type;
this.cookie = cookie;
this.refreshDone = refreshDone;
this.refreshDeletes = refreshDeletes;
this.entryUUIDs = entryUUIDs;
}
/**
* Creates a new sync info intermediate response with a type of
* {@link ContentSyncInfoType#NEW_COOKIE}.
*
* @param cookie The updated state cookie for the synchronization session.
* It must not be {@code null}.
* @param controls An optional set of controls to include in the response.
* It may be {@code null} or empty if no controls should be
* included.
*
* @return The created sync info intermediate response.
*/
public static ContentSyncInfoIntermediateResponse createNewCookieResponse(
final ASN1OctetString cookie, final Control... controls)
{
Validator.ensureNotNull(cookie);
final ContentSyncInfoType type = ContentSyncInfoType.NEW_COOKIE;
return new ContentSyncInfoIntermediateResponse(type,
encodeValue(type, cookie, false, null, false),
cookie, false, false, null, controls);
}
/**
* Creates a new sync info intermediate response with a type of
* {@link ContentSyncInfoType#REFRESH_DELETE}.
*
* @param cookie The updated state cookie for the synchronization
* session. It may be {@code null} if no new cookie is
* available.
* @param refreshDone Indicates whether the refresh phase of the
* synchronization operation has completed.
* @param controls An optional set of controls to include in the
* response. It may be {@code null} or empty if no
* controls should be included.
*
* @return The created sync info intermediate response.
*/
public static ContentSyncInfoIntermediateResponse createRefreshDeleteResponse(
final ASN1OctetString cookie, final boolean refreshDone,
final Control... controls)
{
final ContentSyncInfoType type = ContentSyncInfoType.REFRESH_DELETE;
return new ContentSyncInfoIntermediateResponse(type,
encodeValue(type, cookie, refreshDone, null, false),
cookie, refreshDone, false, null, controls);
}
/**
* Creates a new sync info intermediate response with a type of
* {@link ContentSyncInfoType#REFRESH_PRESENT}.
*
* @param cookie The updated state cookie for the synchronization
* session. It may be {@code null} if no new cookie is
* available.
* @param refreshDone Indicates whether the refresh phase of the
* synchronization operation has completed.
* @param controls An optional set of controls to include in the
* response. It may be {@code null} or empty if no
* controls should be included.
*
* @return The created sync info intermediate response.
*/
public static ContentSyncInfoIntermediateResponse
createRefreshPresentResponse(final ASN1OctetString cookie,
final boolean refreshDone,
final Control... controls)
{
final ContentSyncInfoType type = ContentSyncInfoType.REFRESH_PRESENT;
return new ContentSyncInfoIntermediateResponse(type,
encodeValue(type, cookie, refreshDone, null, false),
cookie, refreshDone, false, null, controls);
}
/**
* Creates a new sync info intermediate response with a type of
* {@link ContentSyncInfoType#SYNC_ID_SET}.
*
* @param cookie The updated state cookie for the synchronization
* session. It may be {@code null} if no new cookie
* is available.
* @param entryUUIDs The set of entryUUIDs for the entries referenced in
* this response. It must not be {@code null}.
* @param refreshDeletes Indicates whether the entryUUIDs represent entries
* that have been removed rather than those that have
* remained unchanged.
* @param controls An optional set of controls to include in the
* response. It may be {@code null} or empty if no
* controls should be included.
*
* @return The created sync info intermediate response.
*/
public static ContentSyncInfoIntermediateResponse createSyncIDSetResponse(
final ASN1OctetString cookie, final List entryUUIDs,
final boolean refreshDeletes, final Control... controls)
{
Validator.ensureNotNull(entryUUIDs);
final ContentSyncInfoType type = ContentSyncInfoType.SYNC_ID_SET;
return new ContentSyncInfoIntermediateResponse(type,
encodeValue(type, cookie, false, entryUUIDs, refreshDeletes),
cookie, false, refreshDeletes,
Collections.unmodifiableList(entryUUIDs), controls);
}
/**
* Decodes the provided generic intermediate response as a sync info
* intermediate response.
*
* @param r The intermediate response to be decoded as a sync info
* intermediate response. It must not be {@code null}.
*
* @return The decoded sync info intermediate response.
*
* @throws LDAPException If a problem occurs while trying to decode the
* provided intermediate response as a sync info
* response.
*/
public static ContentSyncInfoIntermediateResponse decode(
final IntermediateResponse r)
throws LDAPException
{
final ASN1OctetString value = r.getValue();
if (value == null)
{
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_SYNC_INFO_IR_NO_VALUE.get());
}
final ASN1Element valueElement;
try
{
valueElement = ASN1Element.decode(value.getValue());
}
catch (final Exception e)
{
Debug.debugException(e);
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_SYNC_INFO_IR_VALUE_NOT_ELEMENT.get(
StaticUtils.getExceptionMessage(e)), e);
}
final ContentSyncInfoType type =
ContentSyncInfoType.valueOf(valueElement.getType());
if (type == null)
{
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_SYNC_INFO_IR_VALUE_UNRECOGNIZED_TYPE.get(
StaticUtils.toHex(valueElement.getType())));
}
ASN1OctetString cookie = null;
boolean refreshDone = false;
boolean refreshDeletes = false;
List entryUUIDs = null;
try
{
switch (type)
{
case NEW_COOKIE:
cookie = new ASN1OctetString(valueElement.getValue());
break;
case REFRESH_DELETE:
case REFRESH_PRESENT:
refreshDone = true;
ASN1Sequence s = valueElement.decodeAsSequence();
for (final ASN1Element e : s.elements())
{
switch (e.getType())
{
case ASN1Constants.UNIVERSAL_OCTET_STRING_TYPE:
cookie = ASN1OctetString.decodeAsOctetString(e);
break;
case ASN1Constants.UNIVERSAL_BOOLEAN_TYPE:
refreshDone = ASN1Boolean.decodeAsBoolean(e).booleanValue();
break;
default:
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_SYNC_INFO_IR_VALUE_INVALID_SEQUENCE_TYPE.get(
type.name(), StaticUtils.toHex(e.getType())));
}
}
break;
case SYNC_ID_SET:
s = valueElement.decodeAsSequence();
for (final ASN1Element e : s.elements())
{
switch (e.getType())
{
case ASN1Constants.UNIVERSAL_OCTET_STRING_TYPE:
cookie = ASN1OctetString.decodeAsOctetString(e);
break;
case ASN1Constants.UNIVERSAL_BOOLEAN_TYPE:
refreshDeletes = ASN1Boolean.decodeAsBoolean(e).booleanValue();
break;
case ASN1Constants.UNIVERSAL_SET_TYPE:
final ASN1Set uuidSet = ASN1Set.decodeAsSet(e);
final ASN1Element[] uuidElements = uuidSet.elements();
entryUUIDs = new ArrayList<>(uuidElements.length);
for (final ASN1Element uuidElement : uuidElements)
{
try
{
entryUUIDs.add(StaticUtils.decodeUUID(
uuidElement.getValue()));
}
catch (final ParseException pe)
{
Debug.debugException(pe);
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_SYNC_INFO_IR_INVALID_UUID.get(type.name(),
pe.getMessage()), pe);
}
}
break;
default:
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_SYNC_INFO_IR_VALUE_INVALID_SEQUENCE_TYPE.get(
type.name(), StaticUtils.toHex(e.getType())));
}
}
if (entryUUIDs == null)
{
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_SYNC_INFO_IR_NO_UUID_SET.get(type.name()));
}
break;
}
}
catch (final LDAPException le)
{
throw le;
}
catch (final Exception e)
{
Debug.debugException(e);
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_SYNC_INFO_IR_VALUE_DECODING_ERROR.get(
StaticUtils.getExceptionMessage(e)), e);
}
return new ContentSyncInfoIntermediateResponse(type, value, cookie,
refreshDone, refreshDeletes, entryUUIDs, r.getControls());
}
/**
* Encodes the provided information into a form suitable for use as the value
* of this intermediate response.
*
* @param type The type for this sync info message.
* @param cookie The updated sync state cookie.
* @param refreshDone Indicates whether the refresh phase of the
* synchronization operation is complete.
* @param entryUUIDs The set of entryUUIDs for the entries referenced
* in this message.
* @param refreshDeletes Indicates whether the associated entryUUIDs are for
* entries that have been removed.
*
* @return The encoded value.
*/
private static ASN1OctetString encodeValue(final ContentSyncInfoType type,
final ASN1OctetString cookie,
final boolean refreshDone,
final List entryUUIDs,
final boolean refreshDeletes)
{
final ASN1Element e;
switch (type)
{
case NEW_COOKIE:
e = new ASN1OctetString(type.getType(), cookie.getValue());
break;
case REFRESH_DELETE:
case REFRESH_PRESENT:
ArrayList l = new ArrayList<>(2);
if (cookie != null)
{
l.add(cookie);
}
if (! refreshDone)
{
l.add(new ASN1Boolean(refreshDone));
}
e = new ASN1Sequence(type.getType(), l);
break;
case SYNC_ID_SET:
l = new ArrayList<>(3);
if (cookie != null)
{
l.add(cookie);
}
if (refreshDeletes)
{
l.add(new ASN1Boolean(refreshDeletes));
}
final ArrayList uuidElements =
new ArrayList<>(entryUUIDs.size());
for (final UUID uuid : entryUUIDs)
{
uuidElements.add(new ASN1OctetString(StaticUtils.encodeUUID(uuid)));
}
l.add(new ASN1Set(uuidElements));
e = new ASN1Sequence(type.getType(), l);
break;
default:
// This should never happen.
throw new AssertionError("Unexpected sync info type: " + type.name());
}
return new ASN1OctetString(e.encode());
}
/**
* Retrieves the type of content synchronization information represented in
* this response.
*
* @return The type of content synchronization information represented in
* this response.
*/
public ContentSyncInfoType getType()
{
return type;
}
/**
* Retrieves an updated state cookie for the synchronization session, if
* available. It will always be non-{@code null} for a type of
* {@link ContentSyncInfoType#NEW_COOKIE}, and may or may not be {@code null}
* for other types.
*
* @return An updated state cookie for the synchronization session, or
* {@code null} if none is available.
*/
public ASN1OctetString getCookie()
{
return cookie;
}
/**
* Indicates whether the refresh phase of the synchronization operation has
* completed. This is only applicable for the
* {@link ContentSyncInfoType#REFRESH_DELETE} and
* {@link ContentSyncInfoType#REFRESH_PRESENT} types.
*
* @return {@code true} if the refresh phase of the synchronization operation
* has completed, or {@code false} if not or if it is not applicable
* for this message type.
*/
public boolean refreshDone()
{
return refreshDone;
}
/**
* Retrieves a list of the entryUUID values for the entries referenced in this
* message. This is only applicable for the
* {@link ContentSyncInfoType#SYNC_ID_SET} type.
*
* @return A list of the entryUUID values for the entries referenced in this
* message, or {@code null} if it is not applicable for this message
* type.
*/
public List getEntryUUIDs()
{
return entryUUIDs;
}
/**
* Indicates whether the provided set of UUIDs represent entries that have
* been removed. This is only applicable for the
* {@link ContentSyncInfoType#SYNC_ID_SET} type.
*
* @return {@code true} if the associated set of entryUUIDs represent entries
* that have been deleted, or {@code false} if they represent entries
* that remain unchanged or if it is not applicable for this message
* type.
*/
public boolean refreshDeletes()
{
return refreshDeletes;
}
/**
* {@inheritDoc}
*/
@Override()
public String getIntermediateResponseName()
{
return INFO_INTERMEDIATE_RESPONSE_NAME_SYNC_INFO.get();
}
/**
* {@inheritDoc}
*/
@Override()
public String valueToString()
{
final StringBuilder buffer = new StringBuilder();
buffer.append("syncInfoType='");
buffer.append(type.name());
buffer.append('\'');
if (cookie != null)
{
buffer.append(" cookie='");
StaticUtils.toHex(cookie.getValue(), buffer);
buffer.append('\'');
}
switch (type)
{
case REFRESH_DELETE:
case REFRESH_PRESENT:
buffer.append(" refreshDone='");
buffer.append(refreshDone);
buffer.append('\'');
break;
case SYNC_ID_SET:
buffer.append(" entryUUIDs={");
final Iterator iterator = entryUUIDs.iterator();
while (iterator.hasNext())
{
buffer.append('\'');
buffer.append(iterator.next().toString());
buffer.append('\'');
if (iterator.hasNext())
{
buffer.append(',');
}
}
buffer.append('}');
break;
case NEW_COOKIE:
default:
// No additional content is needed.
break;
}
return buffer.toString();
}
/**
* {@inheritDoc}
*/
@Override()
public void toString(final StringBuilder buffer)
{
buffer.append("ContentSyncInfoIntermediateResponse(");
final int messageID = getMessageID();
if (messageID >= 0)
{
buffer.append("messageID=");
buffer.append(messageID);
buffer.append(", ");
}
buffer.append("type='");
buffer.append(type.name());
buffer.append('\'');
if (cookie != null)
{
buffer.append(", cookie='");
StaticUtils.toHex(cookie.getValue(), buffer);
buffer.append("', ");
}
switch (type)
{
case NEW_COOKIE:
// No additional content is needed.
break;
case REFRESH_DELETE:
case REFRESH_PRESENT:
buffer.append(", refreshDone=");
buffer.append(refreshDone);
break;
case SYNC_ID_SET:
buffer.append(", entryUUIDs={");
final Iterator iterator = entryUUIDs.iterator();
while (iterator.hasNext())
{
buffer.append('\'');
buffer.append(iterator.next());
buffer.append('\'');
if (iterator.hasNext())
{
buffer.append(',');
}
}
buffer.append("}, refreshDeletes=");
buffer.append(refreshDeletes);
break;
}
buffer.append(')');
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy