001/* 002 * Copyright 2018-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2018-2019 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.sdk.unboundidds.logs; 022 023 024 025import java.util.Collections; 026import java.util.List; 027 028import com.unboundid.ldap.sdk.ChangeType; 029import com.unboundid.ldap.sdk.ReadOnlyEntry; 030import com.unboundid.ldap.sdk.unboundidds.controls.SoftDeleteRequestControl; 031import com.unboundid.ldif.LDIFAddChangeRecord; 032import com.unboundid.ldif.LDIFChangeRecord; 033import com.unboundid.ldif.LDIFDeleteChangeRecord; 034import com.unboundid.ldif.LDIFException; 035import com.unboundid.ldif.LDIFReader; 036import com.unboundid.util.Debug; 037import com.unboundid.util.StaticUtils; 038import com.unboundid.util.ThreadSafety; 039import com.unboundid.util.ThreadSafetyLevel; 040 041import static com.unboundid.ldap.sdk.unboundidds.logs.LogMessages.*; 042 043 044 045/** 046 * This class provides a data structure that holds information about an audit 047 * log message that represents an add operation. 048 * <BR> 049 * <BLOCKQUOTE> 050 * <B>NOTE:</B> This class, and other classes within the 051 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 052 * supported for use against Ping Identity, UnboundID, and 053 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 054 * for proprietary functionality or for external specifications that are not 055 * considered stable or mature enough to be guaranteed to work in an 056 * interoperable way with other types of LDAP servers. 057 * </BLOCKQUOTE> 058 */ 059@ThreadSafety(level= ThreadSafetyLevel.COMPLETELY_THREADSAFE) 060public final class AddAuditLogMessage 061 extends AuditLogMessage 062{ 063 /** 064 * Retrieves the serial version UID for this serializable class. 065 */ 066 private static final long serialVersionUID = -4103749134439291911L; 067 068 069 070 // Indicates whether the add operation represents an undelete of a 071 // soft-deleted entry. 072 private final Boolean isUndelete; 073 074 // An LDIF change record that encapsulates the change represented by this add 075 // audit log message. 076 private final LDIFAddChangeRecord addChangeRecord; 077 078 // The entry included in the undelete request. 079 private final ReadOnlyEntry undeleteRequestEntry; 080 081 082 083 /** 084 * Creates a new add audit log message from the provided set of lines. 085 * 086 * @param logMessageLines The lines that comprise the log message. It must 087 * not be {@code null} or empty, and it must not 088 * contain any blank lines, although it may contain 089 * comments. In fact, it must contain at least one 090 * comment line that appears before any non-comment 091 * lines (but possibly after other comment lines) 092 * that serves as the message header. 093 * 094 * @throws AuditLogException If a problem is encountered while processing 095 * the provided list of log message lines. 096 */ 097 public AddAuditLogMessage(final String... logMessageLines) 098 throws AuditLogException 099 { 100 this(StaticUtils.toList(logMessageLines), logMessageLines); 101 } 102 103 104 105 /** 106 * Creates a new add audit log message from the provided set of lines. 107 * 108 * @param logMessageLines The lines that comprise the log message. It must 109 * not be {@code null} or empty, and it must not 110 * contain any blank lines, although it may contain 111 * comments. In fact, it must contain at least one 112 * comment line that appears before any non-comment 113 * lines (but possibly after other comment lines) 114 * that serves as the message header. 115 * 116 * @throws AuditLogException If a problem is encountered while processing 117 * the provided list of log message lines. 118 */ 119 public AddAuditLogMessage(final List<String> logMessageLines) 120 throws AuditLogException 121 { 122 this(logMessageLines, StaticUtils.toArray(logMessageLines, String.class)); 123 } 124 125 126 127 /** 128 * Creates a new add audit log message from the provided information. 129 * 130 * @param logMessageLineList The lines that comprise the log message as a 131 * list. 132 * @param logMessageLineArray The lines that comprise the log message as an 133 * array. 134 * 135 * @throws AuditLogException If a problem is encountered while processing 136 * the provided list of log message lines. 137 */ 138 private AddAuditLogMessage(final List<String> logMessageLineList, 139 final String[] logMessageLineArray) 140 throws AuditLogException 141 { 142 super(logMessageLineList); 143 144 try 145 { 146 final LDIFChangeRecord changeRecord = 147 LDIFReader.decodeChangeRecord(logMessageLineArray); 148 if (!(changeRecord instanceof LDIFAddChangeRecord)) 149 { 150 throw new AuditLogException(logMessageLineList, 151 ERR_ADD_AUDIT_LOG_MESSAGE_CHANGE_TYPE_NOT_ADD.get( 152 changeRecord.getChangeType().getName(), 153 ChangeType.ADD.getName())); 154 } 155 156 addChangeRecord = (LDIFAddChangeRecord) changeRecord; 157 } 158 catch (final LDIFException e) 159 { 160 Debug.debugException(e); 161 throw new AuditLogException(logMessageLineList, 162 ERR_ADD_AUDIT_LOG_MESSAGE_LINES_NOT_CHANGE_RECORD.get( 163 StaticUtils.getExceptionMessage(e)), 164 e); 165 } 166 167 isUndelete = getNamedValueAsBoolean("isUndelete", getHeaderNamedValues()); 168 undeleteRequestEntry = decodeCommentedEntry("Undelete request entry", 169 logMessageLineList, null); 170 } 171 172 173 174 /** 175 * Creates a new add audit log message from the provided set of lines. 176 * 177 * @param logMessageLines The lines that comprise the log message. It must 178 * not be {@code null} or empty, and it must not 179 * contain any blank lines, although it may contain 180 * comments. In fact, it must contain at least one 181 * comment line that appears before any non-comment 182 * lines (but possibly after other comment lines) 183 * that serves as the message header. 184 * @param addChangeRecord The LDIF add change record that is described by 185 * the provided log message lines. 186 * 187 * @throws AuditLogException If a problem is encountered while processing 188 * the provided list of log message lines. 189 */ 190 AddAuditLogMessage(final List<String> logMessageLines, 191 final LDIFAddChangeRecord addChangeRecord) 192 throws AuditLogException 193 { 194 super(logMessageLines); 195 196 this.addChangeRecord = addChangeRecord; 197 198 isUndelete = getNamedValueAsBoolean("isUndelete", getHeaderNamedValues()); 199 undeleteRequestEntry = decodeCommentedEntry("Undelete request entry", 200 logMessageLines, null); 201 } 202 203 204 205 /** 206 * {@inheritDoc} 207 */ 208 @Override() 209 public String getDN() 210 { 211 return addChangeRecord.getDN(); 212 } 213 214 215 216 /** 217 * Retrieves a read-only representation of the entry that was added. 218 * 219 * @return A read-only representation of the entry that was added. 220 */ 221 public ReadOnlyEntry getEntry() 222 { 223 return new ReadOnlyEntry(addChangeRecord.getEntryToAdd()); 224 } 225 226 227 228 /** 229 * Retrieves the value of the "isUndelete" flag from this log message, which 230 * indicates whether the add operation attempted to undelete a previously 231 * soft-deleted entry, if available. 232 * 233 * @return The value of the "isUndelete" flag from this log message, or 234 * {@code null} if it is not available. 235 */ 236 public Boolean getIsUndelete() 237 { 238 return isUndelete; 239 } 240 241 242 243 /** 244 * Retrieves the entry that comprised the undelete request, available. 245 * 246 * @return The entry that comprised the undelete request, or {@code null} if 247 * it is not available. 248 */ 249 public ReadOnlyEntry getUndeleteRequestEntry() 250 { 251 return undeleteRequestEntry; 252 } 253 254 255 256 /** 257 * {@inheritDoc} 258 */ 259 @Override() 260 public ChangeType getChangeType() 261 { 262 return ChangeType.ADD; 263 } 264 265 266 267 /** 268 * {@inheritDoc} 269 */ 270 @Override() 271 public LDIFAddChangeRecord getChangeRecord() 272 { 273 return addChangeRecord; 274 } 275 276 277 278 /** 279 * {@inheritDoc} 280 */ 281 @Override() 282 public boolean isRevertible() 283 { 284 // Add audit log messages are always reversible. 285 return true; 286 } 287 288 289 290 /** 291 * {@inheritDoc} 292 */ 293 @Override() 294 public List<LDIFChangeRecord> getRevertChangeRecords() 295 { 296 if ((isUndelete != null) && isUndelete) 297 { 298 return Collections.<LDIFChangeRecord>singletonList( 299 new LDIFDeleteChangeRecord( 300 SoftDeleteRequestControl.createSoftDeleteRequest( 301 addChangeRecord.getDN(), false, true))); 302 } 303 else 304 { 305 return Collections.<LDIFChangeRecord>singletonList( 306 new LDIFDeleteChangeRecord(addChangeRecord.getDN())); 307 } 308 } 309 310 311 312 /** 313 * {@inheritDoc} 314 */ 315 @Override() 316 public void toString(final StringBuilder buffer) 317 { 318 buffer.append(getUncommentedHeaderLine()); 319 buffer.append("; changeType=add; dn=\""); 320 buffer.append(addChangeRecord.getDN()); 321 buffer.append('\"'); 322 } 323}