Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2010-2024 Ping Identity Corporation
* All Rights Reserved.
*/
/*
* Copyright 2010-2024 Ping Identity Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright (C) 2010-2024 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.unboundidds.extensions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.unboundid.asn1.ASN1Boolean;
import com.unboundid.asn1.ASN1Element;
import com.unboundid.asn1.ASN1Integer;
import com.unboundid.asn1.ASN1OctetString;
import com.unboundid.asn1.ASN1Sequence;
import com.unboundid.ldap.sdk.Control;
import com.unboundid.ldap.sdk.ExtendedResult;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.util.Base64;
import com.unboundid.util.Debug;
import com.unboundid.util.NotMutable;
import com.unboundid.util.NotNull;
import com.unboundid.util.Nullable;
import com.unboundid.util.StaticUtils;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*;
/**
* This class provides an extended result that may be used to obtain information
* about the results of processing a get changelog batch extended request.
*
*
* NOTE: This class, and other classes within the
* {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
* supported for use against Ping Identity, UnboundID, and
* Nokia/Alcatel-Lucent 8661 server products. These classes provide support
* for proprietary functionality or for external specifications that are not
* considered stable or mature enough to be guaranteed to work in an
* interoperable way with other types of LDAP servers.
*
*
* The changelog batch result value is encoded as follows:
*
* See the documentation for the {@link GetChangelogBatchExtendedRequest} class
* for an example demonstrating its use.
*/
@NotMutable()
@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
public final class GetChangelogBatchExtendedResult
extends ExtendedResult
{
/**
* The BER type for the resume token element.
*/
private static final byte TYPE_RESUME_TOKEN = (byte) 0x80;
/**
* The BER type for the more changes available element.
*/
private static final byte TYPE_MORE_CHANGES_AVAILABLE = (byte) 0x81;
/**
* The BER type for the changes already purged element.
*/
private static final byte TYPE_CHANGES_ALREADY_PURGED = (byte) 0x82;
/**
* The BER type for the additional info element.
*/
private static final byte TYPE_ADDITIONAL_INFO = (byte) 0x83;
/**
* The BER type for the estimated changes remaining element.
*/
private static final byte TYPE_ESTIMATED_CHANGES_REMAINING = (byte) 0x84;
/**
* The serial version UID for this serializable object.
*/
private static final long serialVersionUID = -1997815252100989148L;
// The resume token for this extended result.
@Nullable private final ASN1OctetString resumeToken;
// Indicates whether some changes in the requested batch may have already
// been purged.
private final boolean changesAlreadyPurged;
// Indicates whether the server has additional results that are immediately
// available without waiting.
private final boolean moreChangesAvailable;
// The estimated number of remaining changes, if available.
private final int estimatedChangesRemaining;
// The number of entries returned to the client.
private final int entryCount;
// A list of the entries returned to the client.
@Nullable private final List entryList;
// A message with additional information about the result.
@Nullable private final String additionalInfo;
/**
* Creates a new get changelog batch extended result with only the generic
* LDAP result information and no extended value.
*
* @param r An LDAP result with general details of the response. It must
* not be {@code null}.
*/
public GetChangelogBatchExtendedResult(@NotNull final LDAPResult r)
{
super(r.getMessageID(), r.getResultCode(), r.getDiagnosticMessage(),
r.getMatchedDN(), r.getReferralURLs(), null, null,
r.getResponseControls());
resumeToken = null;
changesAlreadyPurged = false;
moreChangesAvailable = false;
estimatedChangesRemaining = -1;
entryCount = -1;
entryList = null;
additionalInfo = null;
}
/**
* Creates a new get changelog batch extended result with the provided
* information.
*
* @param r An LDAP result with general details of the
* response. It must not be {@code null}.
* @param entryCount The number of entries returned. It may be
* less than zero to indicate that the number of
* entries is unknown.
* @param resumeToken A token which may be used to resume
* retrieving changes at the point immediately
* after the last change returned. It may be
* {@code null} only if this result represents
* an error that prevented the operation from
* being successfully processed.
* @param moreChangesAvailable Indicates whether there may be more changes
* immediately available to retrieve from the
* server.
* @param changesAlreadyPurged Indicates whether the server may have already
* purged changes after the starting point
* referenced by the associated request.
* @param additionalInfo A message with additional information about
* the status of the processing. It may be
* {@code null} if no additional message is
* available.
*/
public GetChangelogBatchExtendedResult(@NotNull final LDAPResult r,
final int entryCount,
@Nullable final ASN1OctetString resumeToken,
final boolean moreChangesAvailable,
final boolean changesAlreadyPurged,
@Nullable final String additionalInfo)
{
this(r, entryCount, resumeToken, moreChangesAvailable, -1,
changesAlreadyPurged, additionalInfo);
}
/**
* Creates a new get changelog batch extended result with the provided
* information.
*
* @param r An LDAP result with general details of
* the response. It must not be
* {@code null}.
* @param entryCount The number of entries returned. It may
* be less than zero to indicate that the
* number of entries is unknown.
* @param resumeToken A token which may be used to resume
* retrieving changes at the point
* immediately after the last change
* returned. It may be {@code null} only
* if this result represents an error that
* prevented the operation from being
* successfully processed.
* @param moreChangesAvailable Indicates whether there may be more
* changes immediately available to
* retrieve from the server.
* @param estimatedChangesRemaining An estimate of the number of changes
* remaining to be retrieved. A value less
* than zero will be interpreted as
* "unknown".
* @param changesAlreadyPurged Indicates whether the server may have
* already purged changes after the
* starting point referenced by the
* associated request.
* @param additionalInfo A message with additional information
* about the status of the processing. It
* may be {@code null} if no additional
* message is available.
*/
public GetChangelogBatchExtendedResult(@NotNull final LDAPResult r,
final int entryCount,
@Nullable final ASN1OctetString resumeToken,
final boolean moreChangesAvailable,
final int estimatedChangesRemaining,
final boolean changesAlreadyPurged,
@Nullable final String additionalInfo)
{
super(r.getMessageID(), r.getResultCode(), r.getDiagnosticMessage(),
r.getMatchedDN(), r.getReferralURLs(), null,
encodeValue(resumeToken, moreChangesAvailable,
estimatedChangesRemaining, changesAlreadyPurged, additionalInfo),
r.getResponseControls());
this.resumeToken = resumeToken;
this.moreChangesAvailable = moreChangesAvailable;
this.changesAlreadyPurged = changesAlreadyPurged;
this.additionalInfo = additionalInfo;
if (estimatedChangesRemaining >= 0)
{
this.estimatedChangesRemaining = estimatedChangesRemaining;
}
else
{
this.estimatedChangesRemaining = -1;
}
entryList = null;
if (entryCount < 0)
{
this.entryCount = -1;
}
else
{
this.entryCount = entryCount;
}
}
/**
* Creates a new get changelog batch extended result with the provided
* information.
*
* @param extendedResult A generic extended result to be parsed as a get
* changelog batch extended result. It must not be
* {@code null}.
* @param entryCount The number of entries returned to the client. It
* may be less than zero to indicate that the entry
* count is unknown.
*
* @throws LDAPException If the provided extended result cannot be parsed as
* a get changelog batch result.
*/
public GetChangelogBatchExtendedResult(
@NotNull final ExtendedResult extendedResult,
final int entryCount)
throws LDAPException
{
this(extendedResult, entryCount, null);
}
/**
* Creates a new get changelog batch extended result with the provided
* information.
*
* @param extendedResult A generic extended result to be parsed as a get
* changelog batch extended result. It must not be
* {@code null}.
* @param entryList A list of the entries returned to the client. It
* may be empty to indicate that no entries were
* returned, but it must not be {@code null}.
*
* @throws LDAPException If the provided extended result cannot be parsed as
* a get changelog batch result.
*/
public GetChangelogBatchExtendedResult(
@NotNull final ExtendedResult extendedResult,
@NotNull final List entryList)
throws LDAPException
{
this(extendedResult, entryList.size(), entryList);
}
/**
* Creates a new get changelog batch extended result with the provided
* information.
*
* @param r A generic extended result to be parsed as a get
* changelog batch extended result. It must not be
* {@code null}.
* @param entryCount The number of entries returned to the client. It may
* be less than zero to indicate that the entry count is
* unknown.
* @param entryList A list of the entries returned to the client. It may
* be empty to indicate that no entries were returned, or
* {@code null} if the entry list is not available.
*
* @throws LDAPException If the provided extended result cannot be parsed as
* a get changelog batch result.
*/
private GetChangelogBatchExtendedResult(@NotNull final ExtendedResult r,
final int entryCount,
@Nullable final List entryList)
throws LDAPException
{
super(r);
if (entryList == null)
{
this.entryList = null;
}
else
{
this.entryList = Collections.unmodifiableList(entryList);
}
if (entryCount < 0)
{
this.entryCount = -1;
}
else
{
this.entryCount = entryCount;
}
final ASN1OctetString value = r.getValue();
if (value == null)
{
// See if an entry list was provided and we can get a resume token from
// it.
if ((entryList != null) && (! entryList.isEmpty()))
{
resumeToken = entryList.get(entryList.size() - 1).getResumeToken();
}
else
{
resumeToken = null;
}
moreChangesAvailable = false;
estimatedChangesRemaining = -1;
changesAlreadyPurged = false;
additionalInfo = null;
return;
}
final ASN1Element[] valueElements;
try
{
valueElements =
ASN1Sequence.decodeAsSequence(value.getValue()).elements();
}
catch (final Exception e)
{
Debug.debugException(e);
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_GET_CHANGELOG_BATCH_RES_VALUE_NOT_SEQUENCE.get(
StaticUtils.getExceptionMessage(e)), e);
}
ASN1OctetString token = null;
Boolean moreChanges = null;
boolean missingChanges = false;
int changesRemaining = -1;
String message = null;
try
{
for (final ASN1Element e : valueElements)
{
final byte type = e.getType();
switch (type)
{
case TYPE_RESUME_TOKEN:
token = ASN1OctetString.decodeAsOctetString(e);
break;
case TYPE_MORE_CHANGES_AVAILABLE:
moreChanges = ASN1Boolean.decodeAsBoolean(e).booleanValue();
break;
case TYPE_CHANGES_ALREADY_PURGED:
missingChanges = ASN1Boolean.decodeAsBoolean(e).booleanValue();
break;
case TYPE_ADDITIONAL_INFO:
message = ASN1OctetString.decodeAsOctetString(e).stringValue();
break;
case TYPE_ESTIMATED_CHANGES_REMAINING:
changesRemaining = ASN1Integer.decodeAsInteger(e).intValue();
if (changesRemaining < 0)
{
changesRemaining = -1;
}
break;
default:
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_GET_CHANGELOG_BATCH_RES_UNEXPECTED_VALUE_ELEMENT.get(
StaticUtils.toHex(type)));
}
}
}
catch (final LDAPException le)
{
Debug.debugException(le);
throw le;
}
catch (final Exception e)
{
Debug.debugException(e);
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_GET_CHANGELOG_BATCH_RES_ERROR_PARSING_VALUE.get(
StaticUtils.getExceptionMessage(e)), e);
}
if (moreChanges == null)
{
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_GET_CHANGELOG_BATCH_RES_MISSING_MORE.get());
}
resumeToken = token;
moreChangesAvailable = moreChanges;
changesAlreadyPurged = missingChanges;
estimatedChangesRemaining = changesRemaining;
additionalInfo = message;
}
/**
* Encodes the provided information in a form suitable for use as the value of
* this extended result.
*
* @param resumeToken A token which may be used to resume
* retrieving changes at the point
* immediately after the last change
* returned. It may be {@code null} only
* if this result represents an error that
* prevented the operation from being
* successfully processed.
* @param moreChangesAvailable Indicates whether there may be more
* changes immediately available to
* retrieve from the server.
* @param estimatedChangesRemaining An estimate of the number of changes
* remaining to be retrieved. A value less
* than zero will be interpreted as
* "unknown".
* @param changesAlreadyPurged Indicates whether the server may have
* already purged changes after the
* starting point referenced by the
* associated request.
* @param additionalInfo A message with additional information
* about the status of the processing. It
* may be {@code null} if no additional
* message is available.
*
* @return The ASN.1 octet string to use as the result, or {@code null} if
* there should be no value.
*/
@Nullable()
private static ASN1OctetString encodeValue(
@Nullable final ASN1OctetString resumeToken,
final boolean moreChangesAvailable,
final int estimatedChangesRemaining,
final boolean changesAlreadyPurged,
@Nullable final String additionalInfo)
{
final ArrayList elements = new ArrayList<>(5);
if (resumeToken != null)
{
elements.add(new ASN1OctetString(TYPE_RESUME_TOKEN,
resumeToken.getValue()));
}
elements.add(new ASN1Boolean(TYPE_MORE_CHANGES_AVAILABLE,
moreChangesAvailable));
if (estimatedChangesRemaining >= 0)
{
elements.add(new ASN1Integer(TYPE_ESTIMATED_CHANGES_REMAINING,
estimatedChangesRemaining));
}
if (changesAlreadyPurged)
{
elements.add(new ASN1Boolean(TYPE_CHANGES_ALREADY_PURGED,
changesAlreadyPurged));
}
if (additionalInfo != null)
{
elements.add(new ASN1OctetString(TYPE_ADDITIONAL_INFO, additionalInfo));
}
return new ASN1OctetString(new ASN1Sequence(elements).encode());
}
/**
* Retrieves a token that may be used to resume the process of retrieving
* changes at the point after the last change received. It may be
* {@code null} if this result represents an error that prevented the
* operation from being processed successfully.
*
* @return A token that may be used to resume the process of retrieving
* changes at the point after the last change received, or
* {@code null} if none is available.
*/
@Nullable()
public ASN1OctetString getResumeToken()
{
return resumeToken;
}
/**
* Indicates whether the server indicated that more changes may be immediately
* available without waiting. The value of this argument is only meaningful
* if {@link #hasValue()} returns {@code true}.
*
* @return {@code true} if the server indicated that more changes may be
* immediately available without waiting, or {@code false} if not.
*/
public boolean moreChangesAvailable()
{
return moreChangesAvailable;
}
/**
* Retrieves an estimate of the number of changes that may be immediately
* available to be retrieved from the server, if available.
*
* @return An estimate of the number of changes that may be immediately
* available to be retrieved from the server, or -1 if that
* information is not available.
*/
public int getEstimatedChangesRemaining()
{
return estimatedChangesRemaining;
}
/**
* Indicates whether the server indicated that it may have already purged one
* or more changes after the starting point for the associated request and
* therefore the results returned may be missing changes. The value of this
* argument is only meaningful if {@link #hasValue()} returns {@code true}.
*
* @return {@code true} if the server indicated that it may have already
* purged one or more changes after the starting point, or
* {@code false} if not.
*/
public boolean changesAlreadyPurged()
{
return changesAlreadyPurged;
}
/**
* Retrieves a message with additional information about the processing that
* occurred, if available.
*
* @return A message with additional information about the processing that
* occurred, or {@code null} if none is available.
*/
@Nullable()
public String getAdditionalInfo()
{
return additionalInfo;
}
/**
* Retrieves the number of entries returned by the server in the course of
* processing the extended operation. A value of -1 indicates that the entry
* count is not known.
*
* @return The number of entries returned by the server in the course of
* processing the extended operation, 0 if no entries were returned,
* or -1 if the entry count is not known.
*/
public int getEntryCount()
{
return entryCount;
}
/**
* Retrieves a list containing the entries that were returned by the server in
* the course of processing the extended operation, if available. An entry
* list will not be available if a custom {@link ChangelogEntryListener} was
* used for the request, and it may not be available if an error was
* encountered during processing.
*
* @return A list containing the entries that were returned by the server in
* the course of processing the extended operation, or {@code null}
* if an entry list is not available.
*/
@Nullable()
public List getChangelogEntries()
{
return entryList;
}
/**
* {@inheritDoc}
*/
@Override()
@NotNull()
public String getExtendedResultName()
{
return INFO_GET_CHANGELOG_BATCH_RES_NAME.get();
}
/**
* {@inheritDoc}
*/
@Override()
public void toString(@NotNull final StringBuilder buffer)
{
buffer.append("ExtendedResult(resultCode=");
buffer.append(getResultCode());
final int messageID = getMessageID();
if (messageID >= 0)
{
buffer.append(", messageID=");
buffer.append(messageID);
}
final String diagnosticMessage = getDiagnosticMessage();
if (diagnosticMessage != null)
{
buffer.append(", diagnosticMessage='");
buffer.append(diagnosticMessage);
buffer.append('\'');
}
final String matchedDN = getMatchedDN();
if (matchedDN != null)
{
buffer.append(", matchedDN='");
buffer.append(matchedDN);
buffer.append('\'');
}
final String[] referralURLs = getReferralURLs();
if (referralURLs.length > 0)
{
buffer.append(", referralURLs={");
for (int i=0; i < referralURLs.length; i++)
{
if (i > 0)
{
buffer.append(", ");
}
buffer.append(referralURLs[i]);
}
buffer.append('}');
}
if (resumeToken != null)
{
buffer.append(", resumeToken='");
Base64.encode(resumeToken.getValue(), buffer);
buffer.append('\'');
}
buffer.append(", moreChangesAvailable=");
buffer.append(moreChangesAvailable);
buffer.append(", estimatedChangesRemaining=");
buffer.append(estimatedChangesRemaining);
buffer.append(", changesAlreadyPurged=");
buffer.append(changesAlreadyPurged);
if (additionalInfo != null)
{
buffer.append(", additionalInfo='");
buffer.append(additionalInfo);
buffer.append('\'');
}
buffer.append(", entryCount=");
buffer.append(entryCount);
final Control[] responseControls = getResponseControls();
if (responseControls.length > 0)
{
buffer.append(", responseControls={");
for (int i=0; i < responseControls.length; i++)
{
if (i > 0)
{
buffer.append(", ");
}
buffer.append(responseControls[i]);
}
buffer.append('}');
}
buffer.append(')');
}
}