001 /*
002 * Copyright 2011-2012 UnboundID Corp.
003 *
004 * This program is free software; you can redistribute it and/or modify
005 * it under the terms of the GNU General Public License (GPLv2 only)
006 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
007 * as published by the Free Software Foundation.
008 *
009 * This program is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012 * GNU General Public License for more details.
013 *
014 * You should have received a copy of the GNU General Public License
015 * along with this program; if not, see <http://www.gnu.org/licenses>.
016 */
017
018 package com.unboundid.scim.data;
019
020 import com.unboundid.scim.schema.AttributeDescriptor;
021 import com.unboundid.scim.sdk.InvalidResourceException;
022 import com.unboundid.scim.sdk.SCIMAttribute;
023 import com.unboundid.scim.sdk.SCIMAttributeValue;
024
025 import java.util.ArrayList;
026 import java.util.Date;
027 import java.util.List;
028
029 /**
030 * Represents a standard value of a multi-valued attribute.
031 *
032 * @param <T> The value type.
033 */
034 public final class Entry<T>
035 {
036 /**
037 * The <code>AttributeValueResolver</code> that resolves SCIM attribute values
038 * to/from <code>String</code> valued <code>Entry</code> instances.
039 */
040 public static final AttributeValueResolver<Entry<String>>
041 STRINGS_RESOLVER =
042 new AttributeValueResolver<Entry<String>>() {
043 /**
044 * {@inheritDoc}
045 */
046 @Override
047 public Entry<String> toInstance(final SCIMAttributeValue value) {
048 String v =
049 value.getSubAttributeValue("value", STRING_RESOLVER);
050 String t =
051 value.getSubAttributeValue("type", STRING_RESOLVER);
052 Boolean p =
053 value.getSubAttributeValue("primary", BOOLEAN_RESOLVER);
054 String d =
055 value.getSubAttributeValue("display", STRING_RESOLVER);
056
057
058 return new Entry<String>(v, t, p == null ? false : p, d);
059 }
060
061 /**
062 * {@inheritDoc}
063 */
064 @Override
065 public SCIMAttributeValue fromInstance(
066 final AttributeDescriptor attributeDescriptor,
067 final Entry<String> value) throws InvalidResourceException {
068 final List<SCIMAttribute> subAttributes =
069 new ArrayList<SCIMAttribute>(4);
070
071 if (value.value != null)
072 {
073 subAttributes.add(
074 SCIMAttribute.create(
075 attributeDescriptor.getSubAttribute("value"),
076 SCIMAttributeValue.createStringValue(value.value)));
077 }
078
079 if (value.primary)
080 {
081 subAttributes.add(
082 SCIMAttribute.create(
083 attributeDescriptor.getSubAttribute("primary"),
084 SCIMAttributeValue.createBooleanValue(value.primary)));
085 }
086
087 if (value.type != null)
088 {
089 subAttributes.add(
090 SCIMAttribute.create(
091 attributeDescriptor.getSubAttribute("type"),
092 SCIMAttributeValue.createStringValue(value.type)));
093 }
094
095 if(value.display != null)
096 {
097 subAttributes.add(
098 SCIMAttribute.create(
099 attributeDescriptor.getSubAttribute("display"),
100 SCIMAttributeValue.createStringValue(value.display)));
101 }
102
103 return SCIMAttributeValue.createComplexValue(subAttributes);
104 }
105 };
106
107 /**
108 * The <code>AttributeValueResolver</code> that resolves SCIM attribute values
109 * to/from <code>Boolean</code> valued <code>Entry</code> instances.
110 */
111 public static final AttributeValueResolver<Entry<Boolean>>
112 BOOLEANS_RESOLVER =
113 new AttributeValueResolver<Entry<Boolean>>() {
114 /**
115 * {@inheritDoc}
116 */
117 @Override
118 public Entry<Boolean> toInstance(final SCIMAttributeValue value) {
119 Boolean v =
120 value.getSubAttributeValue("value", BOOLEAN_RESOLVER);
121 String t =
122 value.getSubAttributeValue("type", STRING_RESOLVER);
123 Boolean p =
124 value.getSubAttributeValue("primary", BOOLEAN_RESOLVER);
125 String d =
126 value.getSubAttributeValue("display", STRING_RESOLVER);
127
128
129 return new Entry<Boolean>(v, t, p == null ? false : p, d);
130 }
131
132 /**
133 * {@inheritDoc}
134 */
135 @Override
136 public SCIMAttributeValue fromInstance(
137 final AttributeDescriptor attributeDescriptor,
138 final Entry<Boolean> value) throws InvalidResourceException {
139 final List<SCIMAttribute> subAttributes =
140 new ArrayList<SCIMAttribute>(4);
141
142 if (value.value != null)
143 {
144 subAttributes.add(
145 SCIMAttribute.create(
146 attributeDescriptor.getSubAttribute("value"),
147 SCIMAttributeValue.createBooleanValue(value.value)));
148 }
149
150 if (value.primary)
151 {
152 subAttributes.add(
153 SCIMAttribute.create(
154 attributeDescriptor.getSubAttribute("primary"),
155 SCIMAttributeValue.createBooleanValue(value.primary)));
156 }
157
158 if (value.type != null)
159 {
160 subAttributes.add(
161 SCIMAttribute.create(
162 attributeDescriptor.getSubAttribute("type"),
163 SCIMAttributeValue.createStringValue(value.type)));
164 }
165
166 if(value.display != null)
167 {
168 subAttributes.add(
169 SCIMAttribute.create(
170 attributeDescriptor.getSubAttribute("display"),
171 SCIMAttributeValue.createStringValue(value.display)));
172 }
173
174 return SCIMAttributeValue.createComplexValue(subAttributes);
175 }
176 };
177
178 /**
179 * The <code>AttributeValueResolver</code> that resolves SCIM attribute values
180 * to/from <code>byte[]</code> valued <code>Entry</code> instances.
181 */
182 public static final AttributeValueResolver<Entry<byte[]>>
183 BINARIES_RESOLVER =
184 new AttributeValueResolver<Entry<byte[]>>() {
185 /**
186 * {@inheritDoc}
187 */
188 @Override
189 public Entry<byte[]> toInstance(final SCIMAttributeValue value) {
190 byte[] v =
191 value.getSubAttributeValue("value", BINARY_RESOLVER);
192 String t =
193 value.getSubAttributeValue("type", STRING_RESOLVER);
194 Boolean p =
195 value.getSubAttributeValue("primary", BOOLEAN_RESOLVER);
196 String d =
197 value.getSubAttributeValue("display", STRING_RESOLVER);
198
199
200 return new Entry<byte[]>(v, t, p == null ? false : p, d);
201 }
202
203 /**
204 * {@inheritDoc}
205 */
206 @Override
207 public SCIMAttributeValue fromInstance(
208 final AttributeDescriptor attributeDescriptor,
209 final Entry<byte[]> value) throws InvalidResourceException {
210 final List<SCIMAttribute> subAttributes =
211 new ArrayList<SCIMAttribute>(4);
212
213 if (value.value != null)
214 {
215 subAttributes.add(
216 SCIMAttribute.create(
217 attributeDescriptor.getSubAttribute("value"),
218 SCIMAttributeValue.createBinaryValue(value.value)));
219 }
220
221 if (value.primary)
222 {
223 subAttributes.add(
224 SCIMAttribute.create(
225 attributeDescriptor.getSubAttribute("primary"),
226 SCIMAttributeValue.createBooleanValue(value.primary)));
227 }
228
229 if (value.type != null)
230 {
231 subAttributes.add(
232 SCIMAttribute.create(
233 attributeDescriptor.getSubAttribute("type"),
234 SCIMAttributeValue.createStringValue(value.type)));
235 }
236
237 if(value.display != null)
238 {
239 subAttributes.add(
240 SCIMAttribute.create(
241 attributeDescriptor.getSubAttribute("display"),
242 SCIMAttributeValue.createStringValue(value.display)));
243 }
244
245 return SCIMAttributeValue.createComplexValue(subAttributes);
246 }
247 };
248
249 /**
250 * The <code>AttributeValueResolver</code> that resolves SCIM attribute values
251 * to/from <code>Date</code> valued <code>Entry</code> instances.
252 */
253 public static final AttributeValueResolver<Entry<Date>>
254 DATES_RESOLVER =
255 new AttributeValueResolver<Entry<Date>>() {
256 /**
257 * {@inheritDoc}
258 */
259 @Override
260 public Entry<Date> toInstance(final SCIMAttributeValue value) {
261 Date v =
262 value.getSubAttributeValue("value", DATE_RESOLVER);
263 String t =
264 value.getSubAttributeValue("type", STRING_RESOLVER);
265 Boolean p =
266 value.getSubAttributeValue("primary", BOOLEAN_RESOLVER);
267 String d =
268 value.getSubAttributeValue("display", STRING_RESOLVER);
269
270
271 return new Entry<Date>(v, t, p == null ? false : p, d);
272 }
273
274 /**
275 * {@inheritDoc}
276 */
277 @Override
278 public SCIMAttributeValue fromInstance(
279 final AttributeDescriptor attributeDescriptor,
280 final Entry<Date> value) throws InvalidResourceException {
281 final List<SCIMAttribute> subAttributes =
282 new ArrayList<SCIMAttribute>(4);
283
284 if (value.value != null)
285 {
286 subAttributes.add(
287 SCIMAttribute.create(
288 attributeDescriptor.getSubAttribute("value"),
289 SCIMAttributeValue.createDateValue(value.value)));
290 }
291
292 if (value.primary)
293 {
294 subAttributes.add(
295 SCIMAttribute.create(
296 attributeDescriptor.getSubAttribute("primary"),
297 SCIMAttributeValue.createBooleanValue(value.primary)));
298 }
299
300 if (value.type != null)
301 {
302 subAttributes.add(
303 SCIMAttribute.create(
304 attributeDescriptor.getSubAttribute("type"),
305 SCIMAttributeValue.createStringValue(value.type)));
306 }
307
308 if(value.display != null)
309 {
310 subAttributes.add(
311 SCIMAttribute.create(
312 attributeDescriptor.getSubAttribute("display"),
313 SCIMAttributeValue.createStringValue(value.display)));
314 }
315
316 return SCIMAttributeValue.createComplexValue(subAttributes);
317 }
318 };
319
320
321 private T value;
322 private boolean primary;
323 private String type;
324 private String display;
325
326 /**
327 * Constructs an entry instance with the specified information.
328 *
329 * @param value The primary value of this attribute.
330 * @param type The type of attribute for this instance, usually used to
331 * label the preferred function of the given resource.
332 */
333 public Entry(final T value, final String type) {
334 this(value, type, false);
335 }
336
337 /**
338 * Constructs an entry instance with the specified information.
339 *
340 * @param value The primary value of this attribute.
341 * @param type The type of attribute for this instance, usually used to
342 * label the preferred function of the given resource.
343 * @param primary A Boolean value indicating whether this instance of the
344 * multi-valued Attribute is the primary or preferred value of
345 * for this attribute.
346 */
347 public Entry(final T value, final String type, final boolean primary) {
348 this.value = value;
349 this.type = type;
350 this.primary = primary;
351 }
352
353 /**
354 * Constructs an entry instance with the specified information.
355 *
356 * @param value The primary value of this attribute.
357 * @param type The type of attribute for this instance, usually used to
358 * label the preferred function of the given resource.
359 * @param primary A Boolean value indicating whether this instance of the
360 * multi-valued Attribute is the primary or preferred value of
361 * for this attribute.
362 * @param display A human readable name, primarily used for display purposes
363 * where the value is an opaque or complex type such as an id.
364 */
365 public Entry(final T value, final String type, final boolean primary,
366 final String display) {
367 this.value = value;
368 this.type = type;
369 this.primary = primary;
370 this.display = display;
371 }
372
373 /**
374 * Whether this instance of the multi-valued Attribute is the primary or
375 * preferred value of for this attribute.
376 *
377 * @return <code>true</code> if this instance of the multi-valued Attribute is
378 * the primary or preferred value of for this attribute or
379 * <code>false</code> otherwise
380 */
381 public boolean isPrimary() {
382 return primary;
383 }
384
385 /**
386 * Sets whether this instance of the multi-valued Attribute is the primary or
387 * preferred value of for this attribute.
388 *
389 * @param primary <code>true</code> if this instance of the multi-valued
390 * Attribute is the primary or preferred value of for this
391 * attribute or <code>false</code> otherwise.
392 */
393 public void setPrimary(final boolean primary) {
394 this.primary = primary;
395 }
396
397 /**
398 * Retrieves the type of attribute for this instance, usually used to label
399 * the preferred function of the given resource.
400 *
401 * @return The type of attribute for this instance, usually used to label
402 * the preferred function of the given resource.
403 */
404 public String getType() {
405 return type;
406 }
407
408 /**
409 * Sets the type of attribute for this instance, usually used to label
410 * the preferred function of the given resource.
411 *
412 * @param type The type of attribute for this instance, usually used to label
413 * the preferred function of the given resource.
414 */
415 public void setType(final String type) {
416 this.type = type;
417 }
418
419 /**
420 * Retrieves the primary value of this attribute.
421 *
422 * @return The primary value of this attribute.
423 */
424 public T getValue() {
425 return value;
426 }
427
428 /**
429 * Sets the primary value of this attribute.
430 *
431 * @param value The primary value of this attribute.
432 */
433 public void setValue(final T value) {
434 this.value = value;
435 }
436
437 /**
438 * Retrieves the human readable name, primarily used for display purposes
439 * where the value is an opaque or complex type such as an id.
440 *
441 * @return The human readable name.
442 */
443 public String getDisplay() {
444 return this.display;
445 }
446
447 /**
448 * Sets the human readable name, primarily used for display purposes
449 * where the value is an opaque or complex type such as an id.
450 *
451 * @param display The human readable name.
452 */
453 public void setDisplay(final String display) {
454 this.display = display;
455 }
456
457 /**
458 * {@inheritDoc}
459 */
460 @Override
461 public boolean equals(final Object o) {
462 if (this == o) {
463 return true;
464 }
465 if (o == null || getClass() != o.getClass()) {
466 return false;
467 }
468
469 Entry entry = (Entry) o;
470
471 if (primary != entry.primary) {
472 return false;
473 }
474 if (type != null ? !type.equals(entry.type) : entry.type != null) {
475 return false;
476 }
477 if (value != null ? !value.equals(entry.value) : entry.value != null) {
478 return false;
479 }
480 if (display != null ? !display.equals(entry.display) :
481 entry.display != null) {
482 return false;
483 }
484
485 return true;
486 }
487
488 /**
489 * {@inheritDoc}
490 */
491 @Override
492 public int hashCode() {
493 int result = value != null ? value.hashCode() : 0;
494 result = 31 * result + (primary ? 1 : 0);
495 result = 31 * result + (type != null ? type.hashCode() : 0);
496 result = 31 * result + (display != null ? display.hashCode() : 0);
497 return result;
498 }
499
500 /**
501 * {@inheritDoc}
502 */
503 @Override
504 public String toString() {
505 return "Entry{" +
506 "value=" + value +
507 ", type='" + type + '\'' +
508 ", primary=" + primary +
509 ", display=" + display +
510 '}';
511 }
512 }