jDoc, possible leak on crash, new depth option
[jvcard.git] / src / be / nikiroo / jvcard / Data.java
CommitLineData
a3b510ab
NR
1package be.nikiroo.jvcard;
2
3import java.security.InvalidParameterException;
aecb3399 4import java.util.LinkedList;
a3b510ab
NR
5import java.util.List;
6
78e4af97 7/**
f04a32e9 8 * A {@link Data} is a piece of information present in a {@link Contact}. It is
78e4af97 9 * basically a key/value pair with optional types and an optional group name.
f04a32e9
NR
10 * <p>
11 * A {@link Data} can also be binary encoded: in this case, it has an associated
12 * BKey number to identify it.
78e4af97
NR
13 *
14 * @author niki
78e4af97 15 */
26d2bd05 16public class Data extends BaseClass<TypeInfo> {
78e4af97
NR
17 public enum DataPart {
18 FN_FAMILY, FN_GIVEN, FN_ADDITIONAL, // Name
19 FN_PRE, FN_POST, // Pre/Post
20 BDAY_YYYY, BDAY_MM, BDAY_DD, // BDay
f04a32e9 21 // Address:
78e4af97 22 ADR_PBOX, ADR_EXTENDED, ADR_STREET, ADR_CITY, ADR_REGION, ADR_POSTAL_CODE, ADR_COUNTRY
78e4af97
NR
23 }
24
a3b510ab
NR
25 private String name;
26 private String value;
27 private String group;
28 private int b64; // -1 = no, 0 = still not ordered, the rest is order
a3b510ab 29
78e4af97
NR
30 /**
31 * Create a new {@link Data} with the given values.
32 *
33 * @param types
34 * the types of this {@link Data}
35 * @param name
1c03abaf 36 * its name (<b>MUST NOT</b> be NULL)
78e4af97 37 * @param value
1c03abaf 38 * its value (<b>MUST NOT</b> be NULL)
78e4af97 39 * @param group
1c03abaf 40 * its group if any (or NULL if none)
78e4af97 41 */
a3b510ab 42 public Data(List<TypeInfo> types, String name, String value, String group) {
26d2bd05 43 super(types);
a3b510ab 44
1c03abaf
NR
45 this.name = name.toUpperCase();
46 this.value = value.toString(); // crash NOW if null
a3b510ab
NR
47 this.group = group;
48
49 b64 = -1;
26d2bd05 50 for (TypeInfo type : this) {
a3b510ab
NR
51 if (type.getName().equals("ENCODING")
52 && type.getValue().equals("b")) {
53 b64 = 0;
54 break;
55 }
56 }
57 }
58
78e4af97
NR
59 /**
60 * Return the name of this {@link Data}
61 *
62 * @return the name
63 */
a3b510ab
NR
64 public String getName() {
65 return name;
66 }
67
78e4af97
NR
68 /**
69 * Return the value of this {@link Data}
70 *
71 * @return the value
72 */
a3b510ab 73 public String getValue() {
aecb3399
NR
74 return unescape(value);
75 }
30a4aa17
NR
76
77 /**
78 * Change the value of this {@link Data}
79 *
80 * @param value
81 * the new value
82 */
83 public void setValue(String value) {
84 setRawValue(escape(value));
85 }
86
aecb3399 87 /**
30a4aa17 88 * Return the raw value of this {@link Data}
aecb3399 89 *
30a4aa17 90 * @return the raw value
aecb3399
NR
91 */
92 public String getRawValue() {
a3b510ab
NR
93 return value;
94 }
95
78e4af97 96 /**
30a4aa17 97 * Change the raw value of this {@link Data}
78e4af97
NR
98 *
99 * @param value
30a4aa17 100 * the new raw value
78e4af97 101 */
30a4aa17 102 public void setRawValue(String value) {
bcb54330
NR
103 if ((value == null && this.value != null)
104 || (value != null && !value.equals(this.value))) {
105 this.value = value;
106 setDirty();
107 }
108 }
109
aecb3399
NR
110 /**
111 * Return the {@link List} of comma-listed values from this {@link Data}.
112 *
113 * @return the {@link List} of values
114 */
115 public List<String> getValues() {
116 return getList(',');
117 }
118
119 /**
120 * Set the {@link List} of comma-listed values from this {@link Data}.
121 *
122 * @param values
123 * the {@link List} of values
124 */
125 public void setValues(List<String> values) {
126 setList(values, ',');
127 }
128
129 /**
130 * Return the {@link List} of semi-column-listed fields from this
131 * {@link Data}.
132 *
133 * @return the {@link List} of values
134 */
135 public List<String> getFields() {
136 return getList(';');
137 }
138
139 /**
140 * Set the {@link List} of comma-listed values from this {@link Data}.
141 *
142 * @param values
143 * the {@link List} of values
144 */
145 public void setFields(List<String> values) {
146 setList(values, ';');
147 }
148
78e4af97
NR
149 /**
150 * Return the group of this {@link Data}
151 *
152 * @return the group
153 */
a3b510ab
NR
154 public String getGroup() {
155 return group;
156 }
157
176a8327
NR
158 /**
159 * Change the group of this {@link Data}
160 *
161 * @param group
162 * the new group
163 */
164 public void setGroup(String group) {
165 if ((group == null && this.group != null)
166 || (group != null && !group.equals(this.group))) {
167 this.group = group;
168 setDirty();
169 }
170 }
171
78e4af97
NR
172 /**
173 * Return the bkey number of this {@link Data} or -1 if it is not binary.
f04a32e9
NR
174 * <p>
175 * For binary data, as long as the BKey is not processed, it will be 0.
78e4af97 176 *
f04a32e9 177 * @return the bkey, 0 or -1
78e4af97 178 */
a3b510ab
NR
179 public int getB64Key() {
180 return b64;
181 }
182
aecb3399 183 /**
f04a32e9
NR
184 * Check if this {@link Data} is binary (in this case, the BKey will be
185 * present).
aecb3399
NR
186 *
187 * @return TRUE if it is
188 */
189 public boolean isBinary() {
190 return b64 >= 0;
191 }
192
193 /**
7671a249
NR
194 * Return the preferred value of this {@link Data}, or
195 * {@link Integer#MAX_VALUE} if none.
aecb3399 196 *
7671a249 197 * @return the preferred value
aecb3399 198 */
7671a249 199 public int getPreferred() {
aecb3399 200 for (TypeInfo type : this) {
7671a249
NR
201 if (type.getName().equals("PRE")) {
202 try {
203 return Integer.parseInt(type.getValue());
204 } catch (NumberFormatException e) {
205 e.printStackTrace();
206 }
aecb3399
NR
207 }
208 }
209
7671a249 210 return Integer.MAX_VALUE;
aecb3399
NR
211 }
212
78e4af97
NR
213 /**
214 * Change the bkey of this {@link Data}
215 *
216 * @param i
217 * the new bkey
218 *
219 * @throw InvalidParameterException if the {@link Data} is not binary or if
220 * it is but you try to set a negative bkey
221 */
a3b510ab
NR
222 void resetB64Key(int i) {
223 if (!isBinary())
224 throw new InvalidParameterException(
225 "Cannot add a BKey on a non-binary object");
226 if (i < 0)
227 throw new InvalidParameterException(
228 "Cannot remove the BKey on a binary object");
229
230 b64 = i;
231 }
232
78e4af97 233 /**
aecb3399
NR
234 * Return the {@link List} of sep-listed values from this {@link String}
235 * data.
f04a32e9
NR
236 * <p>
237 * Will take the backslash character into account (i.e., a backslash can
238 * escape the given separator).
78e4af97 239 *
aecb3399
NR
240 * @param value
241 * the data
242 *
243 * @param the
244 * separator
245 *
246 * @return the {@link List} of values
78e4af97 247 */
aecb3399
NR
248 private List<String> getList(char sep) {
249 List<String> rep = new LinkedList<String>();
250
251 if (value != null && value.length() > 0) {
252 int last = 0;
253 for (int i = 0; i < value.length(); i++) {
254 if (value.charAt(i) == sep
255 && (i == 0 || value.charAt(i - 1) != '\\')) {
30a4aa17
NR
256 rep.add(value.substring(last, i));
257 last = i + 1;
aecb3399
NR
258 }
259 }
260
30a4aa17
NR
261 if (last < value.length())
262 rep.add(value.substring(last));
aecb3399
NR
263 }
264
265 return rep;
a3b510ab 266 }
e253bd50 267
3634193b 268 /**
aecb3399
NR
269 * Create the {@link String}-encoded {@link List} of sep-listed values from
270 * the given values.
3634193b 271 *
aecb3399
NR
272 * @param values
273 * the {@link List} of values
274 *
275 * @param sep
276 * the separator
277 *
278 * @return the {@link String}
3634193b 279 */
aecb3399
NR
280 private void setList(List<String> values, char sep) {
281 StringBuilder builder = new StringBuilder();
282 boolean first = true;
283 for (String value : values) {
284 if (!first)
285 builder.append(sep);
286
287 builder.append(escape(value));
288
289 first = false;
3634193b
NR
290 }
291
aecb3399 292 value = builder.toString();
3634193b
NR
293 }
294
e253bd50
NR
295 @Override
296 public String getId() {
297 return "" + name;
298 }
299
300 @Override
301 public String getState() {
e4444b0b 302 return ("" + name + value + group).replace(' ', '_');
e253bd50 303 }
812124d1
NR
304
305 @Override
306 public String toString() {
307 String out = name + ": " + value;
308 if (group != null && !group.isEmpty()) {
309 out += " (" + group + ")";
310 }
311 if (b64 >= 0) {
312 out += " [" + b64 + "]";
313 }
314
315 return out;
316 }
a3b510ab 317}