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 2007-2021 Ping Identity Corporation
* All Rights Reserved.
*/
/*
* Copyright 2007-2021 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) 2007-2021 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.ldif;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
import com.unboundid.asn1.ASN1OctetString;
import com.unboundid.ldap.sdk.ChangeType;
import com.unboundid.ldap.sdk.Control;
import com.unboundid.ldap.sdk.DN;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPInterface;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.util.ByteStringBuffer;
import com.unboundid.util.NotExtensible;
import com.unboundid.util.NotNull;
import com.unboundid.util.Nullable;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
import com.unboundid.util.Validator;
/**
* This class provides a base class for LDIF change records, which can be used
* to represent add, delete, modify, and modify DN operations in LDIF form.
*
*
Example
* The following example iterates through all of the change records contained in
* an LDIF file and attempts to apply those changes to a directory server:
*
* LDIFReader ldifReader = new LDIFReader(pathToLDIFFile);
*
* int changesRead = 0;
* int changesProcessed = 0;
* int errorsEncountered = 0;
* while (true)
* {
* LDIFChangeRecord changeRecord;
* try
* {
* changeRecord = ldifReader.readChangeRecord();
* if (changeRecord == null)
* {
* // All changes have been processed.
* break;
* }
*
* changesRead++;
* }
* catch (LDIFException le)
* {
* errorsEncountered++;
* if (le.mayContinueReading())
* {
* // A recoverable error occurred while attempting to read a change
* // record, at or near line number le.getLineNumber()
* // The change record will be skipped, but we'll try to keep reading
* // from the LDIF file.
* continue;
* }
* else
* {
* // An unrecoverable error occurred while attempting to read a change
* // record, at or near line number le.getLineNumber()
* // No further LDIF processing will be performed.
* break;
* }
* }
* catch (IOException ioe)
* {
* // An I/O error occurred while attempting to read from the LDIF file.
* // No further LDIF processing will be performed.
* errorsEncountered++;
* break;
* }
*
* // Try to process the change in a directory server.
* LDAPResult operationResult;
* try
* {
* operationResult = changeRecord.processChange(connection);
* // If we got here, then the change should have been processed
* // successfully.
* changesProcessed++;
* }
* catch (LDAPException le)
* {
* // If we got here, then the change attempt failed.
* operationResult = le.toLDAPResult();
* errorsEncountered++;
* }
* }
*
* ldifReader.close();
*
*/
@NotExtensible()
@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE)
public abstract class LDIFChangeRecord
implements LDIFRecord
{
/**
* The serial version UID for this serializable class.
*/
private static final long serialVersionUID = 6917212392170911115L;
// The set of controls for the LDIF change record.
@NotNull private final List controls;
// The parsed DN for this LDIF change record.
@Nullable private volatile DN parsedDN;
// The DN for this LDIF change record.
@NotNull private final String dn;
/**
* Creates a new LDIF change record with the provided DN.
*
* @param dn The DN of the LDIF change record to create. It must not
* be {@code null}.
* @param controls The set of controls for the change record to create. It
* may be {@code null} or empty if no controls are needed.
*/
protected LDIFChangeRecord(@NotNull final String dn,
@Nullable final List controls)
{
Validator.ensureNotNull(dn);
this.dn = dn;
parsedDN = null;
if (controls == null)
{
this.controls = Collections.emptyList();
}
else
{
this.controls = Collections.unmodifiableList(controls);
}
}
/**
* Retrieves the DN for this LDIF change record.
*
* @return The DN for this LDIF change record.
*/
@Override()
@NotNull()
public final String getDN()
{
return dn;
}
/**
* Retrieves the parsed DN for this LDIF change record.
*
* @return The DN for this LDIF change record.
*
* @throws LDAPException If a problem occurs while trying to parse the DN.
*/
@Override()
@NotNull()
public final DN getParsedDN()
throws LDAPException
{
if (parsedDN == null)
{
parsedDN = new DN(dn);
}
return parsedDN;
}
/**
* Retrieves the type of operation represented by this LDIF change record.
*
* @return The type of operation represented by this LDIF change record.
*/
@NotNull()
public abstract ChangeType getChangeType();
/**
* Retrieves the set of controls for this LDIF change record.
*
* @return The set of controls for this LDIF change record, or an empty array
* if there are no controls.
*/
@NotNull()
public List getControls()
{
return controls;
}
/**
* Creates a duplicate of this LDIF change record with the provided set of
* controls.
*
* @param controls The set of controls to include in the duplicate change
* record. It may be {@code null} or empty if no controls
* should be included.
*
* @return A duplicate of this LDIF change record with the provided set of
* controls.
*/
@NotNull()
public abstract LDIFChangeRecord duplicate(@Nullable Control... controls);
/**
* Apply the change represented by this LDIF change record to a directory
* server using the provided connection. Any controls included in the
* change record will be included in the request.
*
* @param connection The connection to use to apply the change.
*
* @return An object providing information about the result of the operation.
*
* @throws LDAPException If an error occurs while processing this change
* in the associated directory server.
*/
@NotNull()
public final LDAPResult processChange(@NotNull final LDAPInterface connection)
throws LDAPException
{
return processChange(connection, true);
}
/**
* Apply the change represented by this LDIF change record to a directory
* server using the provided connection, optionally including any change
* record controls in the request.
*
* @param connection The connection to use to apply the change.
* @param includeControls Indicates whether to include any controls in the
* request.
*
* @return An object providing information about the result of the operation.
*
* @throws LDAPException If an error occurs while processing this change
* in the associated directory server.
*/
@NotNull()
public abstract LDAPResult processChange(@NotNull LDAPInterface connection,
boolean includeControls)
throws LDAPException;
/**
* Retrieves an {@code Entry} representation of this change record. This is
* intended only for internal use by the LDIF reader when operating
* asynchronously in the case that it is not possible to know ahead of time
* whether a user will attempt to read an LDIF record by {@code readEntry} or
* {@code readChangeRecord}. In the event that the LDIF file has an entry
* whose first attribute is "changetype" and the client wants to read it as
* an entry rather than a change record, then this may be used to generate an
* entry representing the change record.
*
* @return The entry representation of this change record.
*
* @throws LDIFException If this change record cannot be represented as a
* valid entry.
*/
@NotNull()
final Entry toEntry()
throws LDIFException
{
return new Entry(toLDIF());
}
/**
* Retrieves a string array whose lines contain an LDIF representation of this
* change record.
*
* @return A string array whose lines contain an LDIF representation of this
* change record.
*/
@Override()
@NotNull()
public final String[] toLDIF()
{
return toLDIF(0);
}
/**
* Retrieves a string array whose lines contain an LDIF representation of this
* change record.
*
* @param wrapColumn The column at which to wrap long lines. A value that
* is less than or equal to two indicates that no
* wrapping should be performed.
*
* @return A string array whose lines contain an LDIF representation of this
* change record.
*/
@Override()
@NotNull()
public abstract String[] toLDIF(int wrapColumn);
/**
* Encodes the provided name and value and adds the result to the provided
* list of lines. This will handle the case in which the encoded name and
* value includes comments about the base64-decoded representation of the
* provided value.
*
* @param name The attribute name to be encoded.
* @param value The attribute value to be encoded.
* @param lines The list of lines to be updated.
*/
static void encodeNameAndValue(@NotNull final String name,
@NotNull final ASN1OctetString value,
@NotNull final List lines)
{
final String line = LDIFWriter.encodeNameAndValue(name, value);
if (LDIFWriter.commentAboutBase64EncodedValues() &&
line.startsWith(name + "::"))
{
final StringTokenizer tokenizer = new StringTokenizer(line, "\r\n");
while (tokenizer.hasMoreTokens())
{
lines.add(tokenizer.nextToken());
}
}
else
{
lines.add(line);
}
}
/**
* Appends an LDIF string representation of this change record to the provided
* buffer.
*
* @param buffer The buffer to which to append an LDIF representation of
* this change record.
*/
@Override()
public final void toLDIF(@NotNull final ByteStringBuffer buffer)
{
toLDIF(buffer, 0);
}
/**
* Appends an LDIF string representation of this change record to the provided
* buffer.
*
* @param buffer The buffer to which to append an LDIF representation of
* this change record.
* @param wrapColumn The column at which to wrap long lines. A value that
* is less than or equal to two indicates that no
* wrapping should be performed.
*/
@Override()
public abstract void toLDIF(@NotNull ByteStringBuffer buffer, int wrapColumn);
/**
* Retrieves an LDIF string representation of this change record.
*
* @return An LDIF string representation of this change record.
*/
@Override()
@NotNull()
public final String toLDIFString()
{
final StringBuilder buffer = new StringBuilder();
toLDIFString(buffer, 0);
return buffer.toString();
}
/**
* Retrieves an LDIF string representation of this change record.
*
* @param wrapColumn The column at which to wrap long lines. A value that
* is less than or equal to two indicates that no
* wrapping should be performed.
*
* @return An LDIF string representation of this change record.
*/
@Override()
@NotNull()
public final String toLDIFString(final int wrapColumn)
{
final StringBuilder buffer = new StringBuilder();
toLDIFString(buffer, wrapColumn);
return buffer.toString();
}
/**
* Appends an LDIF string representation of this change record to the provided
* buffer.
*
* @param buffer The buffer to which to append an LDIF representation of
* this change record.
*/
@Override()
public final void toLDIFString(@NotNull final StringBuilder buffer)
{
toLDIFString(buffer, 0);
}
/**
* Appends an LDIF string representation of this change record to the provided
* buffer.
*
* @param buffer The buffer to which to append an LDIF representation of
* this change record.
* @param wrapColumn The column at which to wrap long lines. A value that
* is less than or equal to two indicates that no
* wrapping should be performed.
*/
@Override()
public abstract void toLDIFString(@NotNull StringBuilder buffer,
int wrapColumn);
/**
* Retrieves a hash code for this change record.
*
* @return A hash code for this change record.
*/
@Override()
public abstract int hashCode();
/**
* Indicates whether the provided object is equal to this LDIF change record.
*
* @param o The object for which to make the determination.
*
* @return {@code true} if the provided object is equal to this LDIF change
* record, or {@code false} if not.
*/
@Override()
public abstract boolean equals(@Nullable Object o);
/**
* Encodes a string representation of the provided control for use in the
* LDIF representation of the change record.
*
* @param c The control to be encoded.
*
* @return The string representation of the control.
*/
@NotNull()
static ASN1OctetString encodeControlString(@NotNull final Control c)
{
final ByteStringBuffer buffer = new ByteStringBuffer();
buffer.append(c.getOID());
if (c.isCritical())
{
buffer.append(" true");
}
else
{
buffer.append(" false");
}
final ASN1OctetString value = c.getValue();
if (value != null)
{
LDIFWriter.encodeValue(value, buffer);
}
return buffer.toByteString().toASN1OctetString();
}
/**
* Retrieves a single-line string representation of this change record.
*
* @return A single-line string representation of this change record.
*/
@Override()
@NotNull()
public final String toString()
{
final StringBuilder buffer = new StringBuilder();
toString(buffer);
return buffer.toString();
}
/**
* Appends a single-line string representation of this change record to the
* provided buffer.
*
* @param buffer The buffer to which the information should be written.
*/
@Override()
public abstract void toString(@NotNull StringBuilder buffer);
}