Home | History | Annotate | Download | only in content
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.content;
     18 
     19 import android.os.Parcel;
     20 import android.os.Parcelable;
     21 import android.util.Log;
     22 
     23 import java.util.ArrayList;
     24 import java.util.HashMap;
     25 import java.util.Map;
     26 import java.util.Set;
     27 
     28 /**
     29  * This class is used to store a set of values that the {@link ContentResolver}
     30  * can process.
     31  */
     32 public final class ContentValues implements Parcelable {
     33     public static final String TAG = "ContentValues";
     34 
     35     /** Holds the actual values */
     36     private HashMap<String, Object> mValues;
     37 
     38     /**
     39      * Creates an empty set of values using the default initial size
     40      */
     41     public ContentValues() {
     42         // Choosing a default size of 8 based on analysis of typical
     43         // consumption by applications.
     44         mValues = new HashMap<String, Object>(8);
     45     }
     46 
     47     /**
     48      * Creates an empty set of values using the given initial size
     49      *
     50      * @param size the initial size of the set of values
     51      */
     52     public ContentValues(int size) {
     53         mValues = new HashMap<String, Object>(size, 1.0f);
     54     }
     55 
     56     /**
     57      * Creates a set of values copied from the given set
     58      *
     59      * @param from the values to copy
     60      */
     61     public ContentValues(ContentValues from) {
     62         mValues = new HashMap<String, Object>(from.mValues);
     63     }
     64 
     65     /**
     66      * Creates a set of values copied from the given HashMap. This is used
     67      * by the Parcel unmarshalling code.
     68      *
     69      * @param values the values to start with
     70      * {@hide}
     71      */
     72     private ContentValues(HashMap<String, Object> values) {
     73         mValues = values;
     74     }
     75 
     76     @Override
     77     public boolean equals(Object object) {
     78         if (!(object instanceof ContentValues)) {
     79             return false;
     80         }
     81         return mValues.equals(((ContentValues) object).mValues);
     82     }
     83 
     84     @Override
     85     public int hashCode() {
     86         return mValues.hashCode();
     87     }
     88 
     89     /**
     90      * Adds a value to the set.
     91      *
     92      * @param key the name of the value to put
     93      * @param value the data for the value to put
     94      */
     95     public void put(String key, String value) {
     96         mValues.put(key, value);
     97     }
     98 
     99     /**
    100      * Adds all values from the passed in ContentValues.
    101      *
    102      * @param other the ContentValues from which to copy
    103      */
    104     public void putAll(ContentValues other) {
    105         mValues.putAll(other.mValues);
    106     }
    107 
    108     /**
    109      * Adds a value to the set.
    110      *
    111      * @param key the name of the value to put
    112      * @param value the data for the value to put
    113      */
    114     public void put(String key, Byte value) {
    115         mValues.put(key, value);
    116     }
    117 
    118     /**
    119      * Adds a value to the set.
    120      *
    121      * @param key the name of the value to put
    122      * @param value the data for the value to put
    123      */
    124     public void put(String key, Short value) {
    125         mValues.put(key, value);
    126     }
    127 
    128     /**
    129      * Adds a value to the set.
    130      *
    131      * @param key the name of the value to put
    132      * @param value the data for the value to put
    133      */
    134     public void put(String key, Integer value) {
    135         mValues.put(key, value);
    136     }
    137 
    138     /**
    139      * Adds a value to the set.
    140      *
    141      * @param key the name of the value to put
    142      * @param value the data for the value to put
    143      */
    144     public void put(String key, Long value) {
    145         mValues.put(key, value);
    146     }
    147 
    148     /**
    149      * Adds a value to the set.
    150      *
    151      * @param key the name of the value to put
    152      * @param value the data for the value to put
    153      */
    154     public void put(String key, Float value) {
    155         mValues.put(key, value);
    156     }
    157 
    158     /**
    159      * Adds a value to the set.
    160      *
    161      * @param key the name of the value to put
    162      * @param value the data for the value to put
    163      */
    164     public void put(String key, Double value) {
    165         mValues.put(key, value);
    166     }
    167 
    168     /**
    169      * Adds a value to the set.
    170      *
    171      * @param key the name of the value to put
    172      * @param value the data for the value to put
    173      */
    174     public void put(String key, Boolean value) {
    175         mValues.put(key, value);
    176     }
    177 
    178     /**
    179      * Adds a value to the set.
    180      *
    181      * @param key the name of the value to put
    182      * @param value the data for the value to put
    183      */
    184     public void put(String key, byte[] value) {
    185         mValues.put(key, value);
    186     }
    187 
    188     /**
    189      * Adds a null value to the set.
    190      *
    191      * @param key the name of the value to make null
    192      */
    193     public void putNull(String key) {
    194         mValues.put(key, null);
    195     }
    196 
    197     /**
    198      * Returns the number of values.
    199      *
    200      * @return the number of values
    201      */
    202     public int size() {
    203         return mValues.size();
    204     }
    205 
    206     /**
    207      * Remove a single value.
    208      *
    209      * @param key the name of the value to remove
    210      */
    211     public void remove(String key) {
    212         mValues.remove(key);
    213     }
    214 
    215     /**
    216      * Removes all values.
    217      */
    218     public void clear() {
    219         mValues.clear();
    220     }
    221 
    222     /**
    223      * Returns true if this object has the named value.
    224      *
    225      * @param key the value to check for
    226      * @return {@code true} if the value is present, {@code false} otherwise
    227      */
    228     public boolean containsKey(String key) {
    229         return mValues.containsKey(key);
    230     }
    231 
    232     /**
    233      * Gets a value. Valid value types are {@link String}, {@link Boolean},
    234      * {@link Number}, and {@code byte[]} implementations.
    235      *
    236      * @param key the value to get
    237      * @return the data for the value, or {@code null} if the value is missing or if {@code null}
    238      *         was previously added with the given {@code key}
    239      */
    240     public Object get(String key) {
    241         return mValues.get(key);
    242     }
    243 
    244     /**
    245      * Gets a value and converts it to a String.
    246      *
    247      * @param key the value to get
    248      * @return the String for the value
    249      */
    250     public String getAsString(String key) {
    251         Object value = mValues.get(key);
    252         return value != null ? value.toString() : null;
    253     }
    254 
    255     /**
    256      * Gets a value and converts it to a Long.
    257      *
    258      * @param key the value to get
    259      * @return the Long value, or {@code null} if the value is missing or cannot be converted
    260      */
    261     public Long getAsLong(String key) {
    262         Object value = mValues.get(key);
    263         try {
    264             return value != null ? ((Number) value).longValue() : null;
    265         } catch (ClassCastException e) {
    266             if (value instanceof CharSequence) {
    267                 try {
    268                     return Long.valueOf(value.toString());
    269                 } catch (NumberFormatException e2) {
    270                     Log.e(TAG, "Cannot parse Long value for " + value + " at key " + key);
    271                     return null;
    272                 }
    273             } else {
    274                 Log.e(TAG, "Cannot cast value for " + key + " to a Long: " + value, e);
    275                 return null;
    276             }
    277         }
    278     }
    279 
    280     /**
    281      * Gets a value and converts it to an Integer.
    282      *
    283      * @param key the value to get
    284      * @return the Integer value, or {@code null} if the value is missing or cannot be converted
    285      */
    286     public Integer getAsInteger(String key) {
    287         Object value = mValues.get(key);
    288         try {
    289             return value != null ? ((Number) value).intValue() : null;
    290         } catch (ClassCastException e) {
    291             if (value instanceof CharSequence) {
    292                 try {
    293                     return Integer.valueOf(value.toString());
    294                 } catch (NumberFormatException e2) {
    295                     Log.e(TAG, "Cannot parse Integer value for " + value + " at key " + key);
    296                     return null;
    297                 }
    298             } else {
    299                 Log.e(TAG, "Cannot cast value for " + key + " to a Integer: " + value, e);
    300                 return null;
    301             }
    302         }
    303     }
    304 
    305     /**
    306      * Gets a value and converts it to a Short.
    307      *
    308      * @param key the value to get
    309      * @return the Short value, or {@code null} if the value is missing or cannot be converted
    310      */
    311     public Short getAsShort(String key) {
    312         Object value = mValues.get(key);
    313         try {
    314             return value != null ? ((Number) value).shortValue() : null;
    315         } catch (ClassCastException e) {
    316             if (value instanceof CharSequence) {
    317                 try {
    318                     return Short.valueOf(value.toString());
    319                 } catch (NumberFormatException e2) {
    320                     Log.e(TAG, "Cannot parse Short value for " + value + " at key " + key);
    321                     return null;
    322                 }
    323             } else {
    324                 Log.e(TAG, "Cannot cast value for " + key + " to a Short: " + value, e);
    325                 return null;
    326             }
    327         }
    328     }
    329 
    330     /**
    331      * Gets a value and converts it to a Byte.
    332      *
    333      * @param key the value to get
    334      * @return the Byte value, or {@code null} if the value is missing or cannot be converted
    335      */
    336     public Byte getAsByte(String key) {
    337         Object value = mValues.get(key);
    338         try {
    339             return value != null ? ((Number) value).byteValue() : null;
    340         } catch (ClassCastException e) {
    341             if (value instanceof CharSequence) {
    342                 try {
    343                     return Byte.valueOf(value.toString());
    344                 } catch (NumberFormatException e2) {
    345                     Log.e(TAG, "Cannot parse Byte value for " + value + " at key " + key);
    346                     return null;
    347                 }
    348             } else {
    349                 Log.e(TAG, "Cannot cast value for " + key + " to a Byte: " + value, e);
    350                 return null;
    351             }
    352         }
    353     }
    354 
    355     /**
    356      * Gets a value and converts it to a Double.
    357      *
    358      * @param key the value to get
    359      * @return the Double value, or {@code null} if the value is missing or cannot be converted
    360      */
    361     public Double getAsDouble(String key) {
    362         Object value = mValues.get(key);
    363         try {
    364             return value != null ? ((Number) value).doubleValue() : null;
    365         } catch (ClassCastException e) {
    366             if (value instanceof CharSequence) {
    367                 try {
    368                     return Double.valueOf(value.toString());
    369                 } catch (NumberFormatException e2) {
    370                     Log.e(TAG, "Cannot parse Double value for " + value + " at key " + key);
    371                     return null;
    372                 }
    373             } else {
    374                 Log.e(TAG, "Cannot cast value for " + key + " to a Double: " + value, e);
    375                 return null;
    376             }
    377         }
    378     }
    379 
    380     /**
    381      * Gets a value and converts it to a Float.
    382      *
    383      * @param key the value to get
    384      * @return the Float value, or {@code null} if the value is missing or cannot be converted
    385      */
    386     public Float getAsFloat(String key) {
    387         Object value = mValues.get(key);
    388         try {
    389             return value != null ? ((Number) value).floatValue() : null;
    390         } catch (ClassCastException e) {
    391             if (value instanceof CharSequence) {
    392                 try {
    393                     return Float.valueOf(value.toString());
    394                 } catch (NumberFormatException e2) {
    395                     Log.e(TAG, "Cannot parse Float value for " + value + " at key " + key);
    396                     return null;
    397                 }
    398             } else {
    399                 Log.e(TAG, "Cannot cast value for " + key + " to a Float: " + value, e);
    400                 return null;
    401             }
    402         }
    403     }
    404 
    405     /**
    406      * Gets a value and converts it to a Boolean.
    407      *
    408      * @param key the value to get
    409      * @return the Boolean value, or {@code null} if the value is missing or cannot be converted
    410      */
    411     public Boolean getAsBoolean(String key) {
    412         Object value = mValues.get(key);
    413         try {
    414             return (Boolean) value;
    415         } catch (ClassCastException e) {
    416             if (value instanceof CharSequence) {
    417                 return Boolean.valueOf(value.toString());
    418             } else if (value instanceof Number) {
    419                 return ((Number) value).intValue() != 0;
    420             } else {
    421                 Log.e(TAG, "Cannot cast value for " + key + " to a Boolean: " + value, e);
    422                 return null;
    423             }
    424         }
    425     }
    426 
    427     /**
    428      * Gets a value that is a byte array. Note that this method will not convert
    429      * any other types to byte arrays.
    430      *
    431      * @param key the value to get
    432      * @return the {@code byte[]} value, or {@code null} is the value is missing or not a
    433      *         {@code byte[]}
    434      */
    435     public byte[] getAsByteArray(String key) {
    436         Object value = mValues.get(key);
    437         if (value instanceof byte[]) {
    438             return (byte[]) value;
    439         } else {
    440             return null;
    441         }
    442     }
    443 
    444     /**
    445      * Returns a set of all of the keys and values
    446      *
    447      * @return a set of all of the keys and values
    448      */
    449     public Set<Map.Entry<String, Object>> valueSet() {
    450         return mValues.entrySet();
    451     }
    452 
    453     /**
    454      * Returns a set of all of the keys
    455      *
    456      * @return a set of all of the keys
    457      */
    458     public Set<String> keySet() {
    459         return mValues.keySet();
    460     }
    461 
    462     public static final Parcelable.Creator<ContentValues> CREATOR =
    463             new Parcelable.Creator<ContentValues>() {
    464         @SuppressWarnings({"deprecation", "unchecked"})
    465         public ContentValues createFromParcel(Parcel in) {
    466             // TODO - what ClassLoader should be passed to readHashMap?
    467             HashMap<String, Object> values = in.readHashMap(null);
    468             return new ContentValues(values);
    469         }
    470 
    471         public ContentValues[] newArray(int size) {
    472             return new ContentValues[size];
    473         }
    474     };
    475 
    476     public int describeContents() {
    477         return 0;
    478     }
    479 
    480     @SuppressWarnings("deprecation")
    481     public void writeToParcel(Parcel parcel, int flags) {
    482         parcel.writeMap(mValues);
    483     }
    484 
    485     /**
    486      * Unsupported, here until we get proper bulk insert APIs.
    487      * {@hide}
    488      */
    489     @Deprecated
    490     public void putStringArrayList(String key, ArrayList<String> value) {
    491         mValues.put(key, value);
    492     }
    493 
    494     /**
    495      * Unsupported, here until we get proper bulk insert APIs.
    496      * {@hide}
    497      */
    498     @SuppressWarnings("unchecked")
    499     @Deprecated
    500     public ArrayList<String> getStringArrayList(String key) {
    501         return (ArrayList<String>) mValues.get(key);
    502     }
    503 
    504     /**
    505      * Returns a string containing a concise, human-readable description of this object.
    506      * @return a printable representation of this object.
    507      */
    508     @Override
    509     public String toString() {
    510         StringBuilder sb = new StringBuilder();
    511         for (String name : mValues.keySet()) {
    512             String value = getAsString(name);
    513             if (sb.length() > 0) sb.append(" ");
    514             sb.append(name + "=" + value);
    515         }
    516         return sb.toString();
    517     }
    518 }
    519