microsoft.exchange.webservices.data.property.complex.UserConfigurationDictionary.java Source code

Java tutorial

Introduction

Here is the source code for microsoft.exchange.webservices.data.property.complex.UserConfigurationDictionary.java

Source

/*
 * The MIT License
 * Copyright (c) 2012 Microsoft Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package microsoft.exchange.webservices.data.property.complex;

import microsoft.exchange.webservices.data.attribute.EditorBrowsable;
import microsoft.exchange.webservices.data.core.EwsServiceXmlReader;
import microsoft.exchange.webservices.data.core.EwsServiceXmlWriter;
import microsoft.exchange.webservices.data.core.EwsUtilities;
import microsoft.exchange.webservices.data.core.XmlAttributeNames;
import microsoft.exchange.webservices.data.core.XmlElementNames;
import microsoft.exchange.webservices.data.core.enumeration.attribute.EditorBrowsableState;
import microsoft.exchange.webservices.data.core.enumeration.property.UserConfigurationDictionaryObjectType;
import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace;
import microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException;
import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException;
import microsoft.exchange.webservices.data.misc.OutParam;
import microsoft.exchange.webservices.data.util.DateTimeUtils;
import org.apache.commons.codec.binary.Base64;

import javax.xml.stream.XMLStreamException;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Represents a user configuration's Dictionary property.
 */
@EditorBrowsable(state = EditorBrowsableState.Never)
public final class UserConfigurationDictionary extends ComplexProperty implements Iterable<Object> {

    // TODO: Consider implementing IsDirty mechanism in ComplexProperty.

    /**
     * The dictionary.
     */
    private Map<Object, Object> dictionary;

    /**
     * The is dirty.
     */
    private boolean isDirty = false;

    /**
     * Initializes a new instance of "UserConfigurationDictionary" class.
     */
    public UserConfigurationDictionary() {
        super();
        this.dictionary = new HashMap<Object, Object>();
    }

    /**
     * Gets the element with the specified key.
     *
     * @param key The key of the element to get or set.
     * @return The element with the specified key.
     */
    public Object getElements(Object key) {
        return this.dictionary.get(key);
    }

    /**
     * Sets the element with the specified key.
     *
     * @param key   The key of the element to get or set
     * @param value the value
     * @throws Exception the exception
     */
    public void setElements(Object key, Object value) throws Exception {
        this.validateEntry(key, value);
        this.dictionary.put(key, value);
        this.changed();
    }

    /**
     * Adds an element with the provided key and value to the user configuration
     * dictionary.
     *
     * @param key   The object to use as the key of the element to add.
     * @param value The object to use as the value of the element to add.
     * @throws Exception the exception
     */
    public void addElement(Object key, Object value) throws Exception {
        this.validateEntry(key, value);
        this.dictionary.put(key, value);
        this.changed();
    }

    /**
     * Determines whether the user configuration dictionary contains an element
     * with the specified key.
     *
     * @param key The key to locate in the user configuration dictionary.
     * @return true if the user configuration dictionary contains an element
     * with the key; otherwise false.
     */
    public boolean containsKey(Object key) {
        return this.dictionary.containsKey(key);
    }

    /**
     * Removes the element with the specified key from the user configuration
     * dictionary.
     *
     * @param key The key of the element to remove.
     * @return true if the element is successfully removed; otherwise false.
     */
    public boolean remove(Object key) {
        boolean isRemoved = false;
        if (key != null) {
            this.dictionary.remove(key);
            isRemoved = true;
        }

        if (isRemoved) {
            this.changed();
        }

        return isRemoved;
    }

    /**
     * Gets the value associated with the specified key.
     *
     * @param key   The key whose value to get.
     * @param value When this method returns, the value associated with the
     *              specified key, if the key is found; otherwise, null.
     * @return true if the user configuration dictionary contains the key;
     * otherwise false.
     */
    public boolean tryGetValue(Object key, OutParam<Object> value) {
        if (this.dictionary.containsKey(key)) {
            value.setParam(this.dictionary.get(key));
            return true;
        } else {
            value.setParam(null);
            return false;
        }

    }

    /**
     * Gets the number of elements in the user configuration dictionary.
     *
     * @return the count
     */
    public int getCount() {
        return this.dictionary.size();
    }

    /**
     * Removes all item from the user configuration dictionary.
     */
    public void clear() {
        if (this.dictionary.size() != 0) {
            this.dictionary.clear();

            this.changed();
        }
    }

    /**
     * Gets the enumerator.
     *
     * @return the enumerator
     */

    /**
     * Returns an enumerator that iterates through
     * the user configuration dictionary.
     *
     * @return An IEnumerator that can be used
     * to iterate through the user configuration dictionary.
     */
    public Iterator<Object> getEnumerator() {
        return (this.dictionary.values().iterator());
    }

    /**
     * Gets the isDirty flag.
     *
     * @return the checks if is dirty
     */
    public boolean getIsDirty() {
        return this.isDirty;
    }

    /**
     * Sets the isDirty flag.
     *
     * @param value the new checks if is dirty
     */
    public void setIsDirty(boolean value) {
        this.isDirty = value;
    }

    /**
     * Instance was changed.
     */
    @Override
    public void changed() {
        super.changed();
        this.isDirty = true;
    }

    /**
     * Writes elements to XML.
     *
     * @param writer accepts EwsServiceXmlWriter
     * @throws XMLStreamException the XML stream exception
     * @throws ServiceXmlSerializationException the service xml serialization exception
     */
    @Override
    public void writeElementsToXml(EwsServiceXmlWriter writer)
            throws XMLStreamException, ServiceXmlSerializationException {
        EwsUtilities.ewsAssert(writer != null, "UserConfigurationDictionary.WriteElementsToXml", "writer is null");
        Iterator<Entry<Object, Object>> it = this.dictionary.entrySet().iterator();
        while (it.hasNext()) {
            Entry<Object, Object> dictionaryEntry = it.next();
            writer.writeStartElement(XmlNamespace.Types, XmlElementNames.DictionaryEntry);
            this.writeObjectToXml(writer, XmlElementNames.DictionaryKey, dictionaryEntry.getKey());
            this.writeObjectToXml(writer, XmlElementNames.DictionaryValue, dictionaryEntry.getValue());
            writer.writeEndElement();
        }
    }

    /**
     * Writes a dictionary object (key or value) to Xml.
     *
     * @param writer           the writer
     * @param xmlElementName   the Xml element name
     * @param dictionaryObject the object to write
     * @throws XMLStreamException the XML stream exception
     * @throws ServiceXmlSerializationException the service xml serialization exception
     */
    private void writeObjectToXml(EwsServiceXmlWriter writer, String xmlElementName, Object dictionaryObject)
            throws XMLStreamException, ServiceXmlSerializationException {
        EwsUtilities.ewsAssert(writer != null, "UserConfigurationDictionary.WriteObjectToXml", "writer is null");
        EwsUtilities.ewsAssert(xmlElementName != null, "UserConfigurationDictionary.WriteObjectToXml",
                "xmlElementName is null");
        writer.writeStartElement(XmlNamespace.Types, xmlElementName);

        if (dictionaryObject == null) {
            EwsUtilities.ewsAssert((!xmlElementName.equals(XmlElementNames.DictionaryKey)),
                    "UserConfigurationDictionary.WriteObjectToXml", "Key is null");

            writer.writeAttributeValue(EwsUtilities.EwsXmlSchemaInstanceNamespacePrefix, XmlAttributeNames.Nil,
                    EwsUtilities.XSTrue);
        } else {
            this.writeObjectValueToXml(writer, dictionaryObject);
        }

        writer.writeEndElement();
    }

    /**
     * Writes a dictionary Object's value to Xml.
     *
     * @param writer           The writer.
     * @param dictionaryObject The dictionary object to write. <br />
     *                         Object values are either:  <br />
     *                         an array of strings, an array of bytes (which will be encoded into base64) <br />
     *                         or a single value. Single values can be: <br />
     *                         - datetime, boolean, byte, int, long, string
     * @throws XMLStreamException the XML stream exception
     * @throws ServiceXmlSerializationException the service xml serialization exception
     */
    private void writeObjectValueToXml(final EwsServiceXmlWriter writer, final Object dictionaryObject)
            throws XMLStreamException, ServiceXmlSerializationException {
        // Preconditions
        if (dictionaryObject == null) {
            throw new NullPointerException("DictionaryObject must not be null");
        }
        if (writer == null) {
            throw new NullPointerException("EwsServiceXmlWriter must not be null");
        }

        // Processing
        final UserConfigurationDictionaryObjectType dictionaryObjectType;
        if (dictionaryObject instanceof String[]) {
            dictionaryObjectType = UserConfigurationDictionaryObjectType.StringArray;
            this.writeEntryTypeToXml(writer, dictionaryObjectType);

            for (String arrayElement : (String[]) dictionaryObject) {
                this.writeEntryValueToXml(writer, arrayElement);
            }
        } else {
            final String valueAsString;
            if (dictionaryObject instanceof String) {
                dictionaryObjectType = UserConfigurationDictionaryObjectType.String;
                valueAsString = String.valueOf(dictionaryObject);
            } else if (dictionaryObject instanceof Boolean) {
                dictionaryObjectType = UserConfigurationDictionaryObjectType.Boolean;
                valueAsString = EwsUtilities.boolToXSBool((Boolean) dictionaryObject);
            } else if (dictionaryObject instanceof Byte) {
                dictionaryObjectType = UserConfigurationDictionaryObjectType.Byte;
                valueAsString = String.valueOf(dictionaryObject);
            } else if (dictionaryObject instanceof Date) {
                dictionaryObjectType = UserConfigurationDictionaryObjectType.DateTime;
                valueAsString = writer.getService()
                        .convertDateTimeToUniversalDateTimeString((Date) dictionaryObject);
            } else if (dictionaryObject instanceof Integer) {
                // removed unsigned integer because in Java, all types are
                // signed, there are no unsigned versions
                dictionaryObjectType = UserConfigurationDictionaryObjectType.Integer32;
                valueAsString = String.valueOf(dictionaryObject);
            } else if (dictionaryObject instanceof Long) {
                // removed unsigned integer because in Java, all types are
                // signed, there are no unsigned versions
                dictionaryObjectType = UserConfigurationDictionaryObjectType.Integer64;
                valueAsString = String.valueOf(dictionaryObject);
            } else if (dictionaryObject instanceof byte[]) {
                dictionaryObjectType = UserConfigurationDictionaryObjectType.ByteArray;
                valueAsString = Base64.encodeBase64String((byte[]) dictionaryObject);
            } else if (dictionaryObject instanceof Byte[]) {
                dictionaryObjectType = UserConfigurationDictionaryObjectType.ByteArray;

                // cast Byte[] to byte[]
                Byte[] from = (Byte[]) dictionaryObject;
                byte[] to = new byte[from.length];
                for (int currentIndex = 0; currentIndex < from.length; currentIndex++) {
                    to[currentIndex] = (byte) from[currentIndex];
                }

                valueAsString = Base64.encodeBase64String(to);
            } else {
                throw new IllegalArgumentException(
                        String.format("Unsupported type: %s", dictionaryObject.getClass().toString()));
            }
            this.writeEntryTypeToXml(writer, dictionaryObjectType);
            this.writeEntryValueToXml(writer, valueAsString);
        }
    }

    /**
     * Writes a dictionary entry type to Xml.
     *
     * @param writer               the writer
     * @param dictionaryObjectType type to write
     * @throws XMLStreamException the XML stream exception
     * @throws ServiceXmlSerializationException the service xml serialization exception
     */
    private void writeEntryTypeToXml(EwsServiceXmlWriter writer,
            UserConfigurationDictionaryObjectType dictionaryObjectType)
            throws XMLStreamException, ServiceXmlSerializationException {
        writer.writeStartElement(XmlNamespace.Types, XmlElementNames.Type);
        writer.writeValue(dictionaryObjectType.toString(), XmlElementNames.Type);
        writer.writeEndElement();
    }

    /**
     * Writes a dictionary entry value to Xml.
     *
     * @param writer the writer
     * @param value  value to write
     * @throws XMLStreamException the XML stream exception
     * @throws ServiceXmlSerializationException the service xml serialization exception
     */
    private void writeEntryValueToXml(EwsServiceXmlWriter writer, String value)
            throws XMLStreamException, ServiceXmlSerializationException {
        writer.writeStartElement(XmlNamespace.Types, XmlElementNames.Value);

        // While an entry value can't be null, if the entry is an array, an
        // element of the array can be null.
        if (value != null) {
            writer.writeValue(value, XmlElementNames.Value);
        }

        writer.writeEndElement();
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * microsoft.exchange.webservices.ComplexProperty#loadFromXml(microsoft.
     * exchange.webservices.EwsServiceXmlReader,
     * microsoft.exchange.webservices.XmlNamespace, java.lang.String)
     */
    @Override
    /**
     * Loads this dictionary from the specified reader.
     * @param reader The reader.
     * @param xmlNamespace The dictionary's XML namespace.
     * @param xmlElementName Name of the XML element
     * representing the dictionary.
     */
    public void loadFromXml(EwsServiceXmlReader reader, XmlNamespace xmlNamespace, String xmlElementName)
            throws Exception {
        super.loadFromXml(reader, xmlNamespace, xmlElementName);

        this.isDirty = false;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * microsoft.exchange.webservices.ComplexProperty#tryReadElementFromXml(
     * microsoft.exchange.webservices.EwsServiceXmlReader)
     */
    @Override
    /**
     * Tries to read element from XML.
     * @param reader The reader.
     * @return True if element was read.
     */
    public boolean tryReadElementFromXml(EwsServiceXmlReader reader) throws Exception {
        reader.ensureCurrentNodeIsStartElement(this.getNamespace(), XmlElementNames.DictionaryEntry);
        this.loadEntry(reader);
        return true;
    }

    /**
     * Loads an entry, consisting of a key value pair, into this dictionary from
     * the specified reader.
     *
     * @param reader The reader.
     * @throws Exception the exception
     */
    private void loadEntry(EwsServiceXmlReader reader) throws Exception {
        EwsUtilities.ewsAssert(reader != null, "UserConfigurationDictionary.LoadEntry", "reader is null");

        Object key;
        Object value = null;

        // Position at DictionaryKey
        reader.readStartElement(this.getNamespace(), XmlElementNames.DictionaryKey);

        key = this.getDictionaryObject(reader);

        // Position at DictionaryValue
        reader.readStartElement(this.getNamespace(), XmlElementNames.DictionaryValue);

        String nil = reader.readAttributeValue(XmlNamespace.XmlSchemaInstance, XmlAttributeNames.Nil);
        boolean hasValue = (nil == null) || (!nil.getClass().equals(Boolean.TYPE));
        if (hasValue) {
            value = this.getDictionaryObject(reader);
        }
        this.dictionary.put(key, value);
    }

    /**
     * Extracts a dictionary object (key or entry value) from the specified
     * reader.
     *
     * @param reader The reader.
     * @return Dictionary object.
     * @throws Exception the exception
     */
    private Object getDictionaryObject(EwsServiceXmlReader reader) throws Exception {
        EwsUtilities.ewsAssert(reader != null, "UserConfigurationDictionary.loadFromXml", "reader is null");
        UserConfigurationDictionaryObjectType type = this.getObjectType(reader);
        List<String> values = this.getObjectValue(reader, type);
        return this.constructObject(type, values, reader);
    }

    /**
     * Extracts a dictionary object (key or entry value) as a string list from
     * the specified reader.
     *
     * @param reader The reader.
     * @param type   The object type.
     * @return String list representing a dictionary object.
     * @throws Exception the exception
     */
    private List<String> getObjectValue(EwsServiceXmlReader reader, UserConfigurationDictionaryObjectType type)
            throws Exception {
        EwsUtilities.ewsAssert(reader != null, "UserConfigurationDictionary.loadFromXml", "reader is null");

        List<String> values = new ArrayList<String>();

        reader.readStartElement(this.getNamespace(), XmlElementNames.Value);

        do {
            String value = null;

            if (reader.isEmptyElement()) {
                // Only string types can be represented with empty values.
                if (type.equals(UserConfigurationDictionaryObjectType.String)
                        || type.equals(UserConfigurationDictionaryObjectType.StringArray)) {
                    value = "";
                } else {
                    EwsUtilities.ewsAssert(false, "UserConfigurationDictionary." + "GetObjectValue",
                            "Empty element passed for type: " + type.toString());

                }

            } else {
                value = reader.readElementValue();
            }

            values.add(value);
            reader.read(); // Position at next element or
            // DictionaryKey/DictionaryValue end element
        } while (reader.isStartElement(this.getNamespace(), XmlElementNames.Value));
        return values;
    }

    /**
     * Extracts the dictionary object (key or entry value) type from the
     * specified reader.
     *
     * @param reader The reader.
     * @return Dictionary object type.
     * @throws Exception the exception
     */
    private UserConfigurationDictionaryObjectType getObjectType(EwsServiceXmlReader reader) throws Exception {
        EwsUtilities.ewsAssert(reader != null, "UserConfigurationDictionary.loadFromXml", "reader is null");

        reader.readStartElement(this.getNamespace(), XmlElementNames.Type);

        String type = reader.readElementValue();
        return UserConfigurationDictionaryObjectType.valueOf(type);
    }

    /**
     * Constructs a dictionary object (key or entry value) from the specified
     * type and string list.
     *
     * @param type   Object type to construct.
     * @param value  Value of the dictionary object as a string list
     * @param reader The reader.
     * @return Dictionary object.
     */
    private Object constructObject(UserConfigurationDictionaryObjectType type, List<String> value,
            EwsServiceXmlReader reader) {
        EwsUtilities.ewsAssert(value != null, "UserConfigurationDictionary.ConstructObject", "value is null");
        EwsUtilities.ewsAssert((value.size() == 1 || type == UserConfigurationDictionaryObjectType.StringArray),

                "UserConfigurationDictionary.ConstructObject", "value is array but type is not StringArray");
        EwsUtilities.ewsAssert(reader != null, "UserConfigurationDictionary.ConstructObject", "reader is null");

        Object dictionaryObject = null;
        if (type.equals(UserConfigurationDictionaryObjectType.Boolean)) {
            dictionaryObject = Boolean.parseBoolean(value.get(0));
        } else if (type.equals(UserConfigurationDictionaryObjectType.Byte)) {
            dictionaryObject = Byte.parseByte(value.get(0));
        } else if (type.equals(UserConfigurationDictionaryObjectType.ByteArray)) {
            dictionaryObject = Base64.decodeBase64(value.get(0));
        } else if (type.equals(UserConfigurationDictionaryObjectType.DateTime)) {
            Date dateTime = DateTimeUtils.convertDateTimeStringToDate(value.get(0));
            if (dateTime != null) {
                dictionaryObject = dateTime;
            } else {
                EwsUtilities.ewsAssert(false, "UserConfigurationDictionary.ConstructObject", "DateTime is null");
            }
        } else if (type.equals(UserConfigurationDictionaryObjectType.Integer32)) {
            dictionaryObject = Integer.parseInt(value.get(0));
        } else if (type.equals(UserConfigurationDictionaryObjectType.Integer64)) {
            dictionaryObject = Long.parseLong(value.get(0));
        } else if (type.equals(UserConfigurationDictionaryObjectType.String)) {
            dictionaryObject = String.valueOf(value.get(0));
        } else if (type.equals(UserConfigurationDictionaryObjectType.StringArray)) {
            dictionaryObject = value.toArray();
        } else if (type.equals(UserConfigurationDictionaryObjectType.UnsignedInteger32)) {
            dictionaryObject = Integer.parseInt(value.get(0));
        } else if (type.equals(UserConfigurationDictionaryObjectType.UnsignedInteger64)) {
            dictionaryObject = Long.parseLong(value.get(0));
        } else {
            EwsUtilities.ewsAssert(false, "UserConfigurationDictionary.ConstructObject",
                    "Type not recognized: " + type.toString());
        }

        return dictionaryObject;
    }

    /**
     * Validates the specified key and value.
     *
     * @param key   The key.
     * @param value The diction dictionary entry key.ary entry value.
     * @throws Exception the exception
     */
    private void validateEntry(Object key, Object value) throws Exception {
        this.validateObject(key);
        this.validateObject(value);

    }

    /**
     * Validates the dictionary object (key or entry value).
     *
     * @param dictionaryObject Object to validate.
     * @throws Exception the exception
     */
    private void validateObject(Object dictionaryObject) throws Exception {
        // Keys may not be null but we rely on the internal dictionary to throw
        // if the key is null.
        if (dictionaryObject != null) {
            if (dictionaryObject.getClass().isArray()) {
                int length = Array.getLength(dictionaryObject);
                Class<?> wrapperType = Array.get(dictionaryObject, 0).getClass();
                Object[] newArray = (Object[]) Array.newInstance(wrapperType, length);
                for (int i = 0; i < length; i++) {
                    newArray[i] = Array.get(dictionaryObject, i);
                }
                this.validateArrayObject(newArray);
            } else {
                this.validateObjectType(dictionaryObject);

            }

        } else {
            throw new NullPointerException();
        }
    }

    /**
     * Validate the array object.
     *
     * @param dictionaryObjectAsArray Object to validate
     * @throws ServiceLocalException the service local exception
     */
    private void validateArrayObject(Object[] dictionaryObjectAsArray) throws ServiceLocalException {
        // This logic is based on
        // Microsoft.Exchange.Data.Storage.ConfigurationDictionary.
        // CheckElementSupportedType().
        // if (dictionaryObjectAsArray is string[])

        if (dictionaryObjectAsArray instanceof String[]) {
            if (dictionaryObjectAsArray.length > 0) {
                for (Object arrayElement : dictionaryObjectAsArray) {
                    if (arrayElement == null) {
                        throw new ServiceLocalException("The array contains at least one null element.");
                    }
                }
            } else {
                throw new ServiceLocalException("The array must contain at least one element.");
            }
        } else if (dictionaryObjectAsArray instanceof Byte[]) {
            if (dictionaryObjectAsArray.length <= 0) {
                throw new ServiceLocalException("The array must contain at least one element.");
            }
        } else {
            throw new ServiceLocalException(String.format(
                    "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.getClass()));
        }
    }

    /**
     * Validates the dictionary object type.
     *
     * @param theObject Object to validate.
     * @throws ServiceLocalException the service local exception
     */
    private void validateObjectType(Object theObject) throws ServiceLocalException {
        // This logic is based on
        // Microsoft.Exchange.Data.Storage.ConfigurationDictionary.
        // CheckElementSupportedType().
        boolean isValidType = false;
        if (theObject != null) {
            if (theObject instanceof String || theObject instanceof Boolean || theObject instanceof Byte
                    || theObject instanceof Long || theObject instanceof Date || theObject instanceof Integer) {
                isValidType = true;
            }
        }

        if (!isValidType) {
            throw new ServiceLocalException(String.format(
                    "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 ? theObject.getClass().toString() : "null")));
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Iterable#iterator()
     */
    @Override
    public Iterator<Object> iterator() {
        return this.dictionary.values().iterator();

    }

}