001 /*
002 * The MIT License
003 * Copyright (c) 2012 Microsoft Corporation
004 *
005 * Permission is hereby granted, free of charge, to any person obtaining a copy
006 * of this software and associated documentation files (the "Software"), to deal
007 * in the Software without restriction, including without limitation the rights
008 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
009 * copies of the Software, and to permit persons to whom the Software is
010 * furnished to do so, subject to the following conditions:
011 *
012 * The above copyright notice and this permission notice shall be included in
013 * all copies or substantial portions of the Software.
014 *
015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
018 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
021 * THE SOFTWARE.
022 */
023
024 package microsoft.exchange.webservices.data.property.complex;
025
026 import microsoft.exchange.webservices.data.attribute.EditorBrowsable;
027 import microsoft.exchange.webservices.data.core.EwsServiceXmlReader;
028 import microsoft.exchange.webservices.data.core.EwsServiceXmlWriter;
029 import microsoft.exchange.webservices.data.core.EwsUtilities;
030 import microsoft.exchange.webservices.data.core.XmlAttributeNames;
031 import microsoft.exchange.webservices.data.core.XmlElementNames;
032 import microsoft.exchange.webservices.data.core.enumeration.attribute.EditorBrowsableState;
033 import microsoft.exchange.webservices.data.core.enumeration.property.UserConfigurationDictionaryObjectType;
034 import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace;
035 import microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException;
036 import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException;
037 import microsoft.exchange.webservices.data.misc.OutParam;
038 import microsoft.exchange.webservices.data.util.DateTimeUtils;
039 import org.apache.commons.codec.binary.Base64;
040
041 import javax.xml.stream.XMLStreamException;
042
043 import java.lang.reflect.Array;
044 import java.util.ArrayList;
045 import java.util.Date;
046 import java.util.HashMap;
047 import java.util.Iterator;
048 import java.util.List;
049 import java.util.Map;
050 import java.util.Map.Entry;
051
052 /**
053 * Represents a user configuration's Dictionary property.
054 */
055 @EditorBrowsable(state = EditorBrowsableState.Never)
056 public final class UserConfigurationDictionary extends ComplexProperty
057 implements Iterable<Object> {
058
059 // TODO: Consider implementing IsDirty mechanism in ComplexProperty.
060
061 /**
062 * The dictionary.
063 */
064 private Map<Object, Object> dictionary;
065
066 /**
067 * The is dirty.
068 */
069 private boolean isDirty = false;
070
071 /**
072 * Initializes a new instance of "UserConfigurationDictionary" class.
073 */
074 public UserConfigurationDictionary() {
075 super();
076 this.dictionary = new HashMap<Object, Object>();
077 }
078
079 /**
080 * Gets the element with the specified key.
081 *
082 * @param key The key of the element to get or set.
083 * @return The element with the specified key.
084 */
085 public Object getElements(Object key) {
086 return this.dictionary.get(key);
087 }
088
089 /**
090 * Sets the element with the specified key.
091 *
092 * @param key The key of the element to get or set
093 * @param value the value
094 * @throws Exception the exception
095 */
096 public void setElements(Object key, Object value) throws Exception {
097 this.validateEntry(key, value);
098 this.dictionary.put(key, value);
099 this.changed();
100 }
101
102 /**
103 * Adds an element with the provided key and value to the user configuration
104 * dictionary.
105 *
106 * @param key The object to use as the key of the element to add.
107 * @param value The object to use as the value of the element to add.
108 * @throws Exception the exception
109 */
110 public void addElement(Object key, Object value) throws Exception {
111 this.validateEntry(key, value);
112 this.dictionary.put(key, value);
113 this.changed();
114 }
115
116 /**
117 * Determines whether the user configuration dictionary contains an element
118 * with the specified key.
119 *
120 * @param key The key to locate in the user configuration dictionary.
121 * @return true if the user configuration dictionary contains an element
122 * with the key; otherwise false.
123 */
124 public boolean containsKey(Object key) {
125 return this.dictionary.containsKey(key);
126 }
127
128 /**
129 * Removes the element with the specified key from the user configuration
130 * dictionary.
131 *
132 * @param key The key of the element to remove.
133 * @return true if the element is successfully removed; otherwise false.
134 */
135 public boolean remove(Object key) {
136 boolean isRemoved = false;
137 if (key != null) {
138 this.dictionary.remove(key);
139 isRemoved = true;
140 }
141
142 if (isRemoved) {
143 this.changed();
144 }
145
146 return isRemoved;
147 }
148
149 /**
150 * Gets the value associated with the specified key.
151 *
152 * @param key The key whose value to get.
153 * @param value When this method returns, the value associated with the
154 * specified key, if the key is found; otherwise, null.
155 * @return true if the user configuration dictionary contains the key;
156 * otherwise false.
157 */
158 public boolean tryGetValue(Object key, OutParam<Object> value) {
159 if (this.dictionary.containsKey(key)) {
160 value.setParam(this.dictionary.get(key));
161 return true;
162 } else {
163 value.setParam(null);
164 return false;
165 }
166
167 }
168
169 /**
170 * Gets the number of elements in the user configuration dictionary.
171 *
172 * @return the count
173 */
174 public int getCount() {
175 return this.dictionary.size();
176 }
177
178 /**
179 * Removes all item from the user configuration dictionary.
180 */
181 public void clear() {
182 if (this.dictionary.size() != 0) {
183 this.dictionary.clear();
184
185 this.changed();
186 }
187 }
188
189 /**
190 * Gets the enumerator.
191 *
192 * @return the enumerator
193 */
194
195 /**
196 * Returns an enumerator that iterates through
197 * the user configuration dictionary.
198 *
199 * @return An IEnumerator that can be used
200 * to iterate through the user configuration dictionary.
201 */
202 public Iterator<Object> getEnumerator() {
203 return (this.dictionary.values().iterator());
204 }
205
206 /**
207 * Gets the isDirty flag.
208 *
209 * @return the checks if is dirty
210 */
211 public boolean getIsDirty() {
212 return this.isDirty;
213 }
214
215 /**
216 * Sets the isDirty flag.
217 *
218 * @param value the new checks if is dirty
219 */
220 public void setIsDirty(boolean value) {
221 this.isDirty = value;
222 }
223
224 /**
225 * Instance was changed.
226 */
227 @Override public void changed() {
228 super.changed();
229 this.isDirty = true;
230 }
231
232 /**
233 * Writes elements to XML.
234 *
235 * @param writer accepts EwsServiceXmlWriter
236 * @throws XMLStreamException the XML stream exception
237 * @throws ServiceXmlSerializationException the service xml serialization exception
238 */
239 @Override
240 public void writeElementsToXml(EwsServiceXmlWriter writer)
241 throws XMLStreamException, ServiceXmlSerializationException {
242 EwsUtilities.ewsAssert(writer != null, "UserConfigurationDictionary.WriteElementsToXml", "writer is null");
243 Iterator<Entry<Object, Object>> it = this.dictionary.entrySet()
244 .iterator();
245 while (it.hasNext()) {
246 Entry<Object, Object> dictionaryEntry = it.next();
247 writer.writeStartElement(XmlNamespace.Types,
248 XmlElementNames.DictionaryEntry);
249 this.writeObjectToXml(writer, XmlElementNames.DictionaryKey,
250 dictionaryEntry.getKey());
251 this.writeObjectToXml(writer, XmlElementNames.DictionaryValue,
252 dictionaryEntry.getValue());
253 writer.writeEndElement();
254 }
255 }
256
257 /**
258 * Writes a dictionary object (key or value) to Xml.
259 *
260 * @param writer the writer
261 * @param xmlElementName the Xml element name
262 * @param dictionaryObject the object to write
263 * @throws XMLStreamException the XML stream exception
264 * @throws ServiceXmlSerializationException the service xml serialization exception
265 */
266 private void writeObjectToXml(EwsServiceXmlWriter writer,
267 String xmlElementName, Object dictionaryObject)
268 throws XMLStreamException, ServiceXmlSerializationException {
269 EwsUtilities.ewsAssert(writer != null, "UserConfigurationDictionary.WriteObjectToXml", "writer is null");
270 EwsUtilities.ewsAssert(xmlElementName != null, "UserConfigurationDictionary.WriteObjectToXml",
271 "xmlElementName is null");
272 writer.writeStartElement(XmlNamespace.Types, xmlElementName);
273
274 if (dictionaryObject == null) {
275 EwsUtilities.ewsAssert((!xmlElementName.equals(XmlElementNames.DictionaryKey)),
276 "UserConfigurationDictionary.WriteObjectToXml", "Key is null");
277
278 writer.writeAttributeValue(
279 EwsUtilities.EwsXmlSchemaInstanceNamespacePrefix,
280 XmlAttributeNames.Nil, EwsUtilities.XSTrue);
281 } else {
282 this.writeObjectValueToXml(writer, dictionaryObject);
283 }
284
285 writer.writeEndElement();
286 }
287
288 /**
289 * Writes a dictionary Object's value to Xml.
290 *
291 * @param writer The writer.
292 * @param dictionaryObject The dictionary object to write. <br />
293 * Object values are either: <br />
294 * an array of strings, an array of bytes (which will be encoded into base64) <br />
295 * or a single value. Single values can be: <br />
296 * - datetime, boolean, byte, int, long, string
297 * @throws XMLStreamException the XML stream exception
298 * @throws ServiceXmlSerializationException the service xml serialization exception
299 */
300 private void writeObjectValueToXml(final EwsServiceXmlWriter writer,
301 final Object dictionaryObject) throws XMLStreamException,
302 ServiceXmlSerializationException {
303 // Preconditions
304 if (dictionaryObject == null) {
305 throw new NullPointerException("DictionaryObject must not be null");
306 }
307 if (writer == null) {
308 throw new NullPointerException(
309 "EwsServiceXmlWriter must not be null");
310 }
311
312 // Processing
313 final UserConfigurationDictionaryObjectType dictionaryObjectType;
314 if (dictionaryObject instanceof String[]) {
315 dictionaryObjectType = UserConfigurationDictionaryObjectType.StringArray;
316 this.writeEntryTypeToXml(writer, dictionaryObjectType);
317
318 for (String arrayElement : (String[]) dictionaryObject) {
319 this.writeEntryValueToXml(writer, arrayElement);
320 }
321 } else {
322 final String valueAsString;
323 if (dictionaryObject instanceof String) {
324 dictionaryObjectType = UserConfigurationDictionaryObjectType.String;
325 valueAsString = String.valueOf(dictionaryObject);
326 } else if (dictionaryObject instanceof Boolean) {
327 dictionaryObjectType = UserConfigurationDictionaryObjectType.Boolean;
328 valueAsString = EwsUtilities
329 .boolToXSBool((Boolean) dictionaryObject);
330 } else if (dictionaryObject instanceof Byte) {
331 dictionaryObjectType = UserConfigurationDictionaryObjectType.Byte;
332 valueAsString = String.valueOf(dictionaryObject);
333 } else if (dictionaryObject instanceof Date) {
334 dictionaryObjectType = UserConfigurationDictionaryObjectType.DateTime;
335 valueAsString = writer.getService()
336 .convertDateTimeToUniversalDateTimeString(
337 (Date) dictionaryObject);
338 } else if (dictionaryObject instanceof Integer) {
339 // removed unsigned integer because in Java, all types are
340 // signed, there are no unsigned versions
341 dictionaryObjectType = UserConfigurationDictionaryObjectType.Integer32;
342 valueAsString = String.valueOf(dictionaryObject);
343 } else if (dictionaryObject instanceof Long) {
344 // removed unsigned integer because in Java, all types are
345 // signed, there are no unsigned versions
346 dictionaryObjectType = UserConfigurationDictionaryObjectType.Integer64;
347 valueAsString = String.valueOf(dictionaryObject);
348 } else if (dictionaryObject instanceof byte[]) {
349 dictionaryObjectType = UserConfigurationDictionaryObjectType.ByteArray;
350 valueAsString = Base64.encodeBase64String((byte[]) dictionaryObject);
351 } else if (dictionaryObject instanceof Byte[]) {
352 dictionaryObjectType = UserConfigurationDictionaryObjectType.ByteArray;
353
354 // cast Byte[] to byte[]
355 Byte[] from = (Byte[]) dictionaryObject;
356 byte[] to = new byte[from.length];
357 for (int currentIndex = 0; currentIndex < from.length; currentIndex++) {
358 to[currentIndex] = (byte) from[currentIndex];
359 }
360
361 valueAsString = Base64.encodeBase64String(to);
362 } else {
363 throw new IllegalArgumentException(String.format(
364 "Unsupported type: %s", dictionaryObject.getClass()
365 .toString()));
366 }
367 this.writeEntryTypeToXml(writer, dictionaryObjectType);
368 this.writeEntryValueToXml(writer, valueAsString);
369 }
370 }
371
372
373 /**
374 * Writes a dictionary entry type to Xml.
375 *
376 * @param writer the writer
377 * @param dictionaryObjectType type to write
378 * @throws XMLStreamException the XML stream exception
379 * @throws ServiceXmlSerializationException the service xml serialization exception
380 */
381 private void writeEntryTypeToXml(EwsServiceXmlWriter writer,
382 UserConfigurationDictionaryObjectType dictionaryObjectType)
383 throws XMLStreamException, ServiceXmlSerializationException {
384 writer.writeStartElement(XmlNamespace.Types, XmlElementNames.Type);
385 writer
386 .writeValue(dictionaryObjectType.toString(),
387 XmlElementNames.Type);
388 writer.writeEndElement();
389 }
390
391 /**
392 * Writes a dictionary entry value to Xml.
393 *
394 * @param writer the writer
395 * @param value value to write
396 * @throws XMLStreamException the XML stream exception
397 * @throws ServiceXmlSerializationException the service xml serialization exception
398 */
399 private void writeEntryValueToXml(EwsServiceXmlWriter writer, String value)
400 throws XMLStreamException, ServiceXmlSerializationException {
401 writer.writeStartElement(XmlNamespace.Types, XmlElementNames.Value);
402
403 // While an entry value can't be null, if the entry is an array, an
404 // element of the array can be null.
405 if (value != null) {
406 writer.writeValue(value, XmlElementNames.Value);
407 }
408
409 writer.writeEndElement();
410 }
411
412 /*
413 * (non-Javadoc)
414 *
415 * @see
416 * microsoft.exchange.webservices.ComplexProperty#loadFromXml(microsoft.
417 * exchange.webservices.EwsServiceXmlReader,
418 * microsoft.exchange.webservices.XmlNamespace, java.lang.String)
419 */
420 @Override
421 /**
422 * Loads this dictionary from the specified reader.
423 * @param reader The reader.
424 * @param xmlNamespace The dictionary's XML namespace.
425 * @param xmlElementName Name of the XML element
426 * representing the dictionary.
427 */ public void loadFromXml(EwsServiceXmlReader reader, XmlNamespace xmlNamespace, String xmlElementName) throws Exception {
428 super.loadFromXml(reader, xmlNamespace, xmlElementName);
429
430 this.isDirty = false;
431 }
432
433 /*
434 * (non-Javadoc)
435 *
436 * @see
437 * microsoft.exchange.webservices.ComplexProperty#tryReadElementFromXml(
438 * microsoft.exchange.webservices.EwsServiceXmlReader)
439 */
440 @Override
441 /**
442 * Tries to read element from XML.
443 * @param reader The reader.
444 * @return True if element was read.
445 */
446 public boolean tryReadElementFromXml(EwsServiceXmlReader reader)
447 throws Exception {
448 reader.ensureCurrentNodeIsStartElement(this.getNamespace(),
449 XmlElementNames.DictionaryEntry);
450 this.loadEntry(reader);
451 return true;
452 }
453
454 /**
455 * Loads an entry, consisting of a key value pair, into this dictionary from
456 * the specified reader.
457 *
458 * @param reader The reader.
459 * @throws Exception the exception
460 */
461 private void loadEntry(EwsServiceXmlReader reader) throws Exception {
462 EwsUtilities.ewsAssert(reader != null, "UserConfigurationDictionary.LoadEntry", "reader is null");
463
464 Object key;
465 Object value = null;
466
467 // Position at DictionaryKey
468 reader.readStartElement(this.getNamespace(),
469 XmlElementNames.DictionaryKey);
470
471 key = this.getDictionaryObject(reader);
472
473 // Position at DictionaryValue
474 reader.readStartElement(this.getNamespace(),
475 XmlElementNames.DictionaryValue);
476
477 String nil = reader.readAttributeValue(XmlNamespace.XmlSchemaInstance,
478 XmlAttributeNames.Nil);
479 boolean hasValue = (nil == null)
480 || (!nil.getClass().equals(Boolean.TYPE));
481 if (hasValue) {
482 value = this.getDictionaryObject(reader);
483 }
484 this.dictionary.put(key, value);
485 }
486
487 /**
488 * Extracts a dictionary object (key or entry value) from the specified
489 * reader.
490 *
491 * @param reader The reader.
492 * @return Dictionary object.
493 * @throws Exception the exception
494 */
495 private Object getDictionaryObject(EwsServiceXmlReader reader)
496 throws Exception {
497 EwsUtilities.ewsAssert(reader != null, "UserConfigurationDictionary.loadFromXml", "reader is null");
498 UserConfigurationDictionaryObjectType type = this.getObjectType(reader);
499 List<String> values = this.getObjectValue(reader, type);
500 return this.constructObject(type, values, reader);
501 }
502
503 /**
504 * Extracts a dictionary object (key or entry value) as a string list from
505 * the specified reader.
506 *
507 * @param reader The reader.
508 * @param type The object type.
509 * @return String list representing a dictionary object.
510 * @throws Exception the exception
511 */
512 private List<String> getObjectValue(EwsServiceXmlReader reader,
513 UserConfigurationDictionaryObjectType type) throws Exception {
514 EwsUtilities.ewsAssert(reader != null, "UserConfigurationDictionary.loadFromXml", "reader is null");
515
516 List<String> values = new ArrayList<String>();
517
518 reader.readStartElement(this.getNamespace(), XmlElementNames.Value);
519
520 do {
521 String value = null;
522
523 if (reader.isEmptyElement()) {
524 // Only string types can be represented with empty values.
525 if (type.equals(UserConfigurationDictionaryObjectType.String)
526 || type
527 .equals(UserConfigurationDictionaryObjectType.
528 StringArray)) {
529 value = "";
530 } else {
531 EwsUtilities
532 .ewsAssert(false, "UserConfigurationDictionary." + "GetObjectValue",
533 "Empty element passed for type: " + type.toString());
534
535 }
536
537 } else {
538 value = reader.readElementValue();
539 }
540
541 values.add(value);
542 reader.read(); // Position at next element or
543 // DictionaryKey/DictionaryValue end element
544 } while (reader.isStartElement(this.getNamespace(),
545 XmlElementNames.Value));
546 return values;
547 }
548
549 /**
550 * Extracts the dictionary object (key or entry value) type from the
551 * specified reader.
552 *
553 * @param reader The reader.
554 * @return Dictionary object type.
555 * @throws Exception the exception
556 */
557 private UserConfigurationDictionaryObjectType getObjectType(
558 EwsServiceXmlReader reader) throws Exception {
559 EwsUtilities.ewsAssert(reader != null, "UserConfigurationDictionary.loadFromXml", "reader is null");
560
561 reader.readStartElement(this.getNamespace(), XmlElementNames.Type);
562
563 String type = reader.readElementValue();
564 return UserConfigurationDictionaryObjectType.valueOf(type);
565 }
566
567 /**
568 * Constructs a dictionary object (key or entry value) from the specified
569 * type and string list.
570 *
571 * @param type Object type to construct.
572 * @param value Value of the dictionary object as a string list
573 * @param reader The reader.
574 * @return Dictionary object.
575 */
576 private Object constructObject(UserConfigurationDictionaryObjectType type,
577 List<String> value, EwsServiceXmlReader reader) {
578 EwsUtilities.ewsAssert(value != null, "UserConfigurationDictionary.ConstructObject", "value is null");
579 EwsUtilities
580 .ewsAssert((value.size() == 1 || type == UserConfigurationDictionaryObjectType.StringArray),
581
582 "UserConfigurationDictionary.ConstructObject",
583 "value is array but type is not StringArray");
584 EwsUtilities
585 .ewsAssert(reader != null, "UserConfigurationDictionary.ConstructObject", "reader is null");
586
587 Object dictionaryObject = null;
588 if (type.equals(UserConfigurationDictionaryObjectType.Boolean)) {
589 dictionaryObject = Boolean.parseBoolean(value.get(0));
590 } else if (type.equals(UserConfigurationDictionaryObjectType.Byte)) {
591 dictionaryObject = Byte.parseByte(value.get(0));
592 } else if (type.equals(UserConfigurationDictionaryObjectType.ByteArray)) {
593 dictionaryObject = Base64.decodeBase64(value.get(0));
594 } else if (type.equals(UserConfigurationDictionaryObjectType.DateTime)) {
595 Date dateTime = DateTimeUtils.convertDateTimeStringToDate(value.get(0));
596 if (dateTime != null) {
597 dictionaryObject = dateTime;
598 } else {
599 EwsUtilities.ewsAssert(false, "UserConfigurationDictionary.ConstructObject", "DateTime is null");
600 }
601 } else if (type.equals(UserConfigurationDictionaryObjectType.Integer32)) {
602 dictionaryObject = Integer.parseInt(value.get(0));
603 } else if (type.equals(UserConfigurationDictionaryObjectType.Integer64)) {
604 dictionaryObject = Long.parseLong(value.get(0));
605 } else if (type.equals(UserConfigurationDictionaryObjectType.String)) {
606 dictionaryObject = String.valueOf(value.get(0));
607 } else if (type
608 .equals(UserConfigurationDictionaryObjectType.StringArray)) {
609 dictionaryObject = value.toArray();
610 } else if (type
611 .equals(UserConfigurationDictionaryObjectType.
612 UnsignedInteger32)) {
613 dictionaryObject = Integer.parseInt(value.get(0));
614 } else if (type
615 .equals(UserConfigurationDictionaryObjectType.
616 UnsignedInteger64)) {
617 dictionaryObject = Long.parseLong(value.get(0));
618 } else {
619 EwsUtilities.ewsAssert(false, "UserConfigurationDictionary.ConstructObject",
620 "Type not recognized: " + type.toString());
621 }
622
623 return dictionaryObject;
624 }
625
626 /**
627 * Validates the specified key and value.
628 *
629 * @param key The key.
630 * @param value The diction dictionary entry key.ary entry value.
631 * @throws Exception the exception
632 */
633 private void validateEntry(Object key, Object value) throws Exception {
634 this.validateObject(key);
635 this.validateObject(value);
636
637 }
638
639 /**
640 * Validates the dictionary object (key or entry value).
641 *
642 * @param dictionaryObject Object to validate.
643 * @throws Exception the exception
644 */
645 private void validateObject(Object dictionaryObject) throws Exception {
646 // Keys may not be null but we rely on the internal dictionary to throw
647 // if the key is null.
648 if (dictionaryObject != null) {
649 if (dictionaryObject.getClass().isArray()) {
650 int length = Array.getLength(dictionaryObject);
651 Class<?> wrapperType = Array.get(dictionaryObject, 0).getClass();
652 Object[] newArray = (Object[]) Array.
653 newInstance(wrapperType, length);
654 for (int i = 0; i < length; i++) {
655 newArray[i] = Array.get(dictionaryObject, i);
656 }
657 this.validateArrayObject(newArray);
658 } else {
659 this.validateObjectType(dictionaryObject);
660
661 }
662
663 } else {
664 throw new NullPointerException();
665 }
666 }
667
668 /**
669 * Validate the array object.
670 *
671 * @param dictionaryObjectAsArray Object to validate
672 * @throws ServiceLocalException the service local exception
673 */
674 private void validateArrayObject(Object[] dictionaryObjectAsArray)
675 throws ServiceLocalException {
676 // This logic is based on
677 // Microsoft.Exchange.Data.Storage.ConfigurationDictionary.
678 // CheckElementSupportedType().
679 // if (dictionaryObjectAsArray is string[])
680
681 if (dictionaryObjectAsArray instanceof String[]) {
682 if (dictionaryObjectAsArray.length > 0) {
683 for (Object arrayElement : dictionaryObjectAsArray) {
684 if (arrayElement == null) {
685 throw new ServiceLocalException("The array contains at least one null element.");
686 }
687 }
688 } else {
689 throw new ServiceLocalException("The array must contain at least one element.");
690 }
691 } else if (dictionaryObjectAsArray instanceof Byte[]) {
692 if (dictionaryObjectAsArray.length <= 0) {
693 throw new ServiceLocalException("The array must contain at least one element.");
694 }
695 } else {
696 throw new ServiceLocalException(String.format(
697 "Objects of type %s can't be added to the dictionary. The following types are supported: string array, byte array, boolean, byte, DateTime, integer, long, string, unsigned integer, and unsigned long.", dictionaryObjectAsArray
698 .getClass()));
699 }
700 }
701
702 /**
703 * Validates the dictionary object type.
704 *
705 * @param theObject Object to validate.
706 * @throws ServiceLocalException the service local exception
707 */
708 private void validateObjectType(Object theObject) throws ServiceLocalException {
709 // This logic is based on
710 // Microsoft.Exchange.Data.Storage.ConfigurationDictionary.
711 // CheckElementSupportedType().
712 boolean isValidType = false;
713 if (theObject != null) {
714 if (theObject instanceof String ||
715 theObject instanceof Boolean ||
716 theObject instanceof Byte ||
717 theObject instanceof Long ||
718 theObject instanceof Date ||
719 theObject instanceof Integer) {
720 isValidType = true;
721 }
722 }
723
724 if (!isValidType) {
725 throw new ServiceLocalException(
726 String.format(
727 "Objects of type %s can't be added to the dictionary. The following types are supported: string array, byte array, boolean, byte, DateTime, integer, long, string, unsigned integer, and unsigned long.", (theObject != null ?
728 theObject.getClass().toString() : "null")));
729 }
730 }
731
732 /*
733 * (non-Javadoc)
734 *
735 * @see java.lang.Iterable#iterator()
736 */
737 @Override
738 public Iterator<Object> iterator() {
739 return this.dictionary.values().iterator();
740
741 }
742
743 }