/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.java.sip.communicator.util; /** * Object which can store user specific key-values. * * @author Damian Minkov */ public class DataObject { /** * The user-specific key-value associations stored in this instance. *

* Like the Widget implementation of Eclipse SWT, the storage type takes * into account that there are likely to be many * DataObject instances and Maps are thus * likely to impose increased memory use. While an array may very well * perform worse than a Map with respect to search, the * mechanism of user-defined key-value associations explicitly states that * it is not guaranteed to be optimized for any particular use and only * covers the most basic cases and performance-savvy code will likely * implement a more optimized solution anyway. *

*/ private Object[] data; /** * Gets the user data * associated with this instance and a specific key. * * @param key the key of the user data associated with this instance to be * retrieved * @return an Object which represents the value associated with * this instance and the specified key; null if no * association with the specified key exists in this instance */ public Object getData(Object key) { if (key == null) throw new NullPointerException("key"); int index = dataIndexOf(key); return (index == -1) ? null : data[index + 1]; } /** * Determines the index in #data of a specific key. * * @param key * the key to retrieve the index in #data of * @return the index in #data of the specified key * if it is contained; -1 if key is not * contained in #data */ private int dataIndexOf(Object key) { if (data != null) for (int index = 0; index < data.length; index += 2) if (key.equals(data[index])) return index; return -1; } /** * Sets a * user-specific association in this instance in the form of a key-value * pair. If the specified key is already associated in this * instance with a value, the existing value is overwritten with the * specified value. *

* The user-defined association created by this method and stored in this * instance is not serialized by this instance and is thus only meant for * runtime use. *

*

* The storage of the user data is implementation-specific and is thus not * guaranteed to be optimized for execution time and memory use. *

* * @param key the key to associate in this instance with the specified value * @param value the value to be associated in this instance with the * specified key */ public void setData(Object key, Object value) { if (key == null) throw new NullPointerException("key"); int index = dataIndexOf(key); if (index == -1) { /* * If value is null, remove the association with key (or just don't * add it). */ if (data == null) { if (value != null) data = new Object[] { key, value }; } else if (value == null) { int length = data.length - 2; if (length > 0) { Object[] newData = new Object[length]; System.arraycopy(data, 0, newData, 0, index); System.arraycopy( data, index + 2, newData, index, length - index); data = newData; } else data = null; } else { int length = data.length; Object[] newData = new Object[length + 2]; System.arraycopy(data, 0, newData, 0, length); data = newData; data[length++] = key; data[length++] = value; } } else data[index + 1] = value; } }