1/*
2 * Copyright (C) 2011 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 */
16package com.android.vcard;
17
18import android.util.Log;
19
20import java.util.ArrayList;
21import java.util.Arrays;
22import java.util.Collection;
23import java.util.HashMap;
24import java.util.HashSet;
25import java.util.List;
26import java.util.Map;
27
28/**
29 * Represents vCard's property, or logical "one line" of each vCard entry.
30 *
31 * e.g.
32 * Given a vCard below, objects for <code>N:name</code>, <code>TEL:1111111111</code> are
33 * "property".
34 *
35 * <code>
36 * BEGIN:VCARD
37 * N:name
38 * TEL:1111111111
39 * END:VCARD
40 * </code>
41 *
42 * vCard's property has three elements: name, parameter (or param), and value. Name is the name
43 * of each property. Parameter or param is additional information for the property. Value is one
44 * or multiple values representing the parameter.
45 *
46 * e.g.
47 * <code>N;CHARSET=UTF-8:Joe;Due;M.;Mr.;Ph.D.</code>, has "N" for name, "CHALSET=UTF-8" for param,
48 * and "Joe;Due;M.;Mr.;Ph.D." for value.
49 *
50 * Usually params are represented as "key=value" pair, but not always
51 * (The property <code>TEL;WORK;VOICE:(111) 555-1212</code> has two params without key "TYPE",
52 * which are same as "TYPE=WORK" and "TYPE=VOICE". In vCard 3.0, we can even express them as
53 * "TYPE=WORK,VOICE").
54 *
55 * Sometimes (not always) value can be separated by semi-colon. In the example above "Joe;Due;;;"
56 * should be interpreted as five strings: "Joe" (for family name), "Due" (for given name), "M."
57 * (for middle name), "Mr." (for prefix), and "Ph.D." (for suffix). Whether the value is
58 * separable or not is specified by vCard specs.
59 */
60public class VCardProperty {
61    private static final String LOG_TAG = VCardConstants.LOG_TAG;
62    private String mName;
63    private List<String> mGroupList;
64
65    private Map<String, Collection<String>> mParameterMap =
66            new HashMap<String, Collection<String>>();
67    private String mRawValue;
68
69    private List<String> mValueList;
70    private byte[] mByteValue;
71
72    public void setName(String name) {
73        if (mName != null) {
74            Log.w(LOG_TAG, String.format("Property name is re-defined " +
75                    "(existing: %s, requested: %s", mName, name));
76        }
77        mName = name;
78    }
79
80    public void addGroup(String group) {
81        if (mGroupList == null) {
82            mGroupList = new ArrayList<String>();
83        }
84        mGroupList.add(group);
85    }
86
87    public void setParameter(final String paramName, final String paramValue) {
88        mParameterMap.clear();
89        addParameter(paramName, paramValue);
90    }
91
92    public void addParameter(final String paramName, final String paramValue) {
93        Collection<String> values;
94        if (!mParameterMap.containsKey(paramName)) {
95            if (paramName.equals("TYPE")) {
96                values = new HashSet<String>();
97            } else {
98                values = new ArrayList<String>();
99            }
100            mParameterMap.put(paramName, values);
101        } else {
102            values = mParameterMap.get(paramName);
103        }
104        values.add(paramValue);
105    }
106
107    public void setRawValue(String rawValue) {
108        mRawValue = rawValue;
109    }
110
111    // TODO: would be much better to have translateRawValue() functionality instead of forcing
112    // VCardParserImpl does this job.
113
114    public void setValues(String... propertyValues) {
115        mValueList = Arrays.asList(propertyValues);
116    }
117
118    public void setValues(List<String> propertyValueList) {
119        mValueList = propertyValueList;
120    }
121
122    public void addValues(String... propertyValues) {
123        if (mValueList == null) {
124            mValueList = Arrays.asList(propertyValues);
125        } else {
126            mValueList.addAll(Arrays.asList(propertyValues));
127        }
128    }
129
130    public void addValues(List<String> propertyValueList) {
131        if (mValueList == null) {
132            mValueList = new ArrayList<String>(propertyValueList);
133        } else {
134            mValueList.addAll(propertyValueList);
135        }
136    }
137
138    public void setByteValue(byte[] byteValue) {
139        mByteValue = byteValue;
140    }
141
142    public String getName() {
143        return mName;
144    }
145
146    public List<String> getGroupList() {
147        return mGroupList;
148    }
149
150    public Map<String, Collection<String>> getParameterMap() {
151        return mParameterMap;
152    }
153
154    public Collection<String> getParameters(String type) {
155        return mParameterMap.get(type);
156    }
157
158    public String getRawValue() {
159        return mRawValue;
160    }
161
162    public List<String> getValueList() {
163        return mValueList;
164    }
165
166    public byte[] getByteValue() {
167        return mByteValue;
168    }
169}
170
171
172