001 /*
002 * Copyright 2011-2015 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2015 UnboundID Corp.
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 */
021 package com.unboundid.ldap.sdk.unboundidds;
022
023
024
025 import java.io.Serializable;
026 import java.util.StringTokenizer;
027
028 import com.unboundid.ldap.sdk.LDAPException;
029 import com.unboundid.ldap.sdk.ResultCode;
030 import com.unboundid.util.Debug;
031 import com.unboundid.util.NotMutable;
032 import com.unboundid.util.StaticUtils;
033 import com.unboundid.util.ThreadSafety;
034 import com.unboundid.util.ThreadSafetyLevel;
035
036 import static com.unboundid.ldap.sdk.unboundidds.UnboundIDDSMessages.*;
037
038
039
040 /**
041 * <BLOCKQUOTE>
042 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID
043 * LDAP SDK for Java. It is not available for use in applications that
044 * include only the Standard Edition of the LDAP SDK, and is not supported for
045 * use in conjunction with non-UnboundID products.
046 * </BLOCKQUOTE>
047 * This class provides a data structure for holding information read from a
048 * value of the ds-changelog-attr-exceeded-max-values-count attribute. Values
049 * should be in the form "attr=X,beforeCount=Y,afterCount=Z", where "X" is the
050 * name of the attribute which had too many values before and/or after the
051 * change, "Y" is the number of values the attribute had before the change, and
052 * "Z" is the number of values the attribute had after the change.
053 */
054 @NotMutable()
055 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
056 public final class ChangeLogEntryAttributeExceededMaxValuesCount
057 implements Serializable
058 {
059 /**
060 * The name of the token used to provide the name of the associated attribute.
061 */
062 private static final String TOKEN_NAME_ATTR = "attr";
063
064
065
066 /**
067 * The name of the token used to provide the number of values before the
068 * change.
069 */
070 private static final String TOKEN_NAME_BEFORE_COUNT =
071 StaticUtils.toLowerCase("beforeCount");
072
073
074
075 /**
076 * The name of the token used to provide the number of values after the
077 * change.
078 */
079 private static final String TOKEN_NAME_AFTER_COUNT =
080 StaticUtils.toLowerCase("afterCount");
081
082
083 /**
084 * The serial version UID for this serializable class.
085 */
086 private static final long serialVersionUID = -4689107630879614032L;
087
088
089
090 // The number of values the associated attribute had after the change.
091 private final long afterCount;
092
093 // The number of values the associated attribute had before the change.
094 private final long beforeCount;
095
096 // The name of the updated attribute for which the number of values exceeded
097 // the maximum display count before and/or after the change.
098 private final String attributeName;
099
100 // The string representation for this element.
101 private final String stringRepresentation;
102
103
104
105 /**
106 * Creates a new instance of this object from the provided string value from
107 * the ds-changelog-attr-exceeded-max-values-count.
108 *
109 * @param s The value to be parsed.
110 *
111 * @throws LDAPException If an error occurred while attempting to parse the
112 * value.
113 */
114 public ChangeLogEntryAttributeExceededMaxValuesCount(final String s)
115 throws LDAPException
116 {
117 stringRepresentation = s;
118
119 String name = null;
120 Long before = null;
121 Long after = null;
122
123 final StringTokenizer tokenizer = new StringTokenizer(s, ",");
124 while (tokenizer.hasMoreTokens())
125 {
126 final String token = tokenizer.nextToken();
127 final int equalPos = token.indexOf('=');
128 if (equalPos < 0)
129 {
130 throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
131 ERR_CHANGELOG_EXCEEDED_VALUE_COUNT_MALFORMED_TOKEN.get(s, token));
132 }
133
134 final String tokenName =
135 StaticUtils.toLowerCase(token.substring(0, equalPos).trim());
136 final String value = token.substring(equalPos+1).trim();
137
138 if (tokenName.equals(TOKEN_NAME_ATTR))
139 {
140 if (name == null)
141 {
142 name = value;
143 }
144 else
145 {
146 throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
147 ERR_CHANGELOG_EXCEEDED_VALUE_COUNT_REPEATED_TOKEN.get(s,
148 tokenName));
149 }
150 }
151 else if (tokenName.equals(TOKEN_NAME_BEFORE_COUNT))
152 {
153 if (before == null)
154 {
155 try
156 {
157 before = Long.parseLong(value);
158 }
159 catch (final Exception e)
160 {
161 Debug.debugException(e);
162 throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
163 ERR_CHANGELOG_EXCEEDED_VALUE_COUNT_MALFORMED_COUNT.get(s,
164 tokenName),
165 e);
166 }
167 }
168 else
169 {
170 throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
171 ERR_CHANGELOG_EXCEEDED_VALUE_COUNT_REPEATED_TOKEN.get(s,
172 tokenName));
173 }
174 }
175 else if (tokenName.equals(TOKEN_NAME_AFTER_COUNT))
176 {
177 if (after == null)
178 {
179 try
180 {
181 after = Long.parseLong(value);
182 }
183 catch (final Exception e)
184 {
185 Debug.debugException(e);
186 throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
187 ERR_CHANGELOG_EXCEEDED_VALUE_COUNT_REPEATED_TOKEN.get(s,
188 tokenName),
189 e);
190 }
191 }
192 else
193 {
194 throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
195 ERR_CHANGELOG_EXCEEDED_VALUE_COUNT_REPEATED_TOKEN.get(s,
196 tokenName));
197 }
198 }
199 }
200
201 if (name == null)
202 {
203 throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
204 ERR_CHANGELOG_EXCEEDED_VALUE_COUNT_MISSING_TOKEN.get(s,
205 TOKEN_NAME_ATTR));
206 }
207
208 if (before == null)
209 {
210 throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
211 ERR_CHANGELOG_EXCEEDED_VALUE_COUNT_MISSING_TOKEN.get(s,
212 TOKEN_NAME_BEFORE_COUNT));
213 }
214
215 if (after == null)
216 {
217 throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
218 ERR_CHANGELOG_EXCEEDED_VALUE_COUNT_MISSING_TOKEN.get(s,
219 TOKEN_NAME_AFTER_COUNT));
220 }
221
222 attributeName = name;
223 beforeCount = before;
224 afterCount = after;
225 }
226
227
228
229 /**
230 * Retrieves the name of the attribute that exceeded the maximum number of
231 * values for inclusion in the ds-changelog-before-values and/or
232 * ds-changelog-after-values attribute of the changelog entry.
233 *
234 * @return The name of the attribute that exceeded the maximum number of
235 * values for inclusion in the ds-changelog-before-values and/or
236 * ds-changelog-after-values attribute of the changelog entry.
237 */
238 public String getAttributeName()
239 {
240 return attributeName;
241 }
242
243
244
245 /**
246 * Retrieves the number of values the specified attribute had in the
247 * target entry before the associated change was processed.
248 *
249 * @return The number of values the specified attribute had in the target
250 * entry before the associated change was processed, or zero if the
251 * attribute was not present in the entry before the change.
252 */
253 public long getBeforeCount()
254 {
255 return beforeCount;
256 }
257
258
259
260 /**
261 * Retrieves the number of values the specified attribute had in the
262 * target entry after the associated change was processed.
263 *
264 * @return The number of values the specified attribute had in the target
265 * entry after the associated change was processed, or zero if the
266 * attribute was not present in the entry after the change.
267 */
268 public long getAfterCount()
269 {
270 return afterCount;
271 }
272
273
274
275 /**
276 * Generates a hash code for this changelog attribute exceeded max values
277 * count object.
278 *
279 * @return The generated hash code for this changelog attribute exceeded max
280 * values count object.
281 */
282 @Override()
283 public int hashCode()
284 {
285 int hashCode = StaticUtils.toLowerCase(attributeName).hashCode();
286
287 hashCode = (int) ((hashCode * 31) + beforeCount);
288 hashCode = (int) ((hashCode * 31) + afterCount);
289
290 return hashCode;
291 }
292
293
294
295 /**
296 * Indicates whether the provided object is equal to this changelog attribute
297 * exceeded max values count object.
298 *
299 * @param o The object for which to make the determination.
300 *
301 * @return {@code true} if the provided object may be considered equal to
302 * this changelog attribute exceeded max values count object, or
303 * {@code false} if not.
304 */
305 @Override()
306 public boolean equals(final Object o)
307 {
308 if (o == null)
309 {
310 return false;
311 }
312
313 if (o == this)
314 {
315 return true;
316 }
317
318 if (! (o instanceof ChangeLogEntryAttributeExceededMaxValuesCount))
319 {
320 return false;
321 }
322
323 final ChangeLogEntryAttributeExceededMaxValuesCount c =
324 (ChangeLogEntryAttributeExceededMaxValuesCount) o;
325 return ((beforeCount == c.beforeCount) && (afterCount == c.afterCount) &&
326 attributeName.equalsIgnoreCase(c.attributeName));
327 }
328
329
330
331 /**
332 * Retrieves a string representation of this changelog entry attribute
333 * exceeded max values count.
334 *
335 * @return A string representation of this changelog entry attribute exceeded
336 * max values count.
337 */
338 @Override()
339 public String toString()
340 {
341 return stringRepresentation;
342 }
343 }