Commit | Line | Data |
---|---|---|
a3b510ab NR |
1 | package be.nikiroo.jvcard; |
2 | ||
26d2bd05 NR |
3 | import java.io.File; |
4 | import java.io.IOException; | |
5 | import java.util.ArrayList; | |
a3b510ab NR |
6 | import java.util.HashMap; |
7 | import java.util.LinkedList; | |
8 | import java.util.List; | |
9 | import java.util.Map; | |
e253bd50 | 10 | import java.util.UUID; |
a3b510ab NR |
11 | |
12 | import be.nikiroo.jvcard.parsers.Format; | |
13 | import be.nikiroo.jvcard.parsers.Parser; | |
7da41ecd | 14 | import be.nikiroo.jvcard.resources.StringUtils; |
a3b510ab NR |
15 | |
16 | /** | |
17 | * A contact is the information that represent a contact person or organisation. | |
18 | * | |
19 | * @author niki | |
20 | * | |
21 | */ | |
26d2bd05 | 22 | public class Contact extends BaseClass<Data> { |
a3b510ab NR |
23 | private int nextBKey = 1; |
24 | private Map<Integer, Data> binaries; | |
a3b510ab NR |
25 | |
26 | /** | |
27 | * Create a new Contact from the given information. Note that the BKeys data | |
28 | * will be reset. | |
29 | * | |
30 | * @param content | |
31 | * the information about the contact | |
32 | */ | |
33 | public Contact(List<Data> content) { | |
26d2bd05 | 34 | super(load(content)); |
a3b510ab NR |
35 | updateBKeys(true); |
36 | } | |
37 | ||
a3b510ab NR |
38 | /** |
39 | * Return the preferred Data field with the given name, or NULL if none. | |
40 | * | |
41 | * @param name | |
42 | * the name to look for | |
43 | * @return the Data field, or NULL | |
44 | */ | |
45 | public Data getPreferredData(String name) { | |
46 | Data first = null; | |
47 | for (Data data : getData(name)) { | |
48 | if (first == null) | |
49 | first = data; | |
3634193b NR |
50 | |
51 | if (data.isPreferred()) | |
52 | return data; | |
a3b510ab NR |
53 | } |
54 | ||
55 | return first; | |
56 | } | |
57 | ||
58 | /** | |
59 | * Return the value of the preferred data field with this name, or NULL if | |
60 | * none (you cannot differentiate a NULL value and no value). | |
61 | * | |
62 | * @param name | |
63 | * the name to look for | |
64 | * @return the value (which can be NULL), or NULL | |
65 | */ | |
66 | public String getPreferredDataValue(String name) { | |
67 | Data data = getPreferredData(name); | |
68 | if (data != null && data.getValue() != null) | |
69 | return data.getValue().trim(); | |
70 | return null; | |
71 | } | |
72 | ||
73 | /** | |
74 | * Get the Data fields that share the given name. | |
75 | * | |
76 | * @param name | |
77 | * the name to ook for | |
78 | * @return a list of Data fields with this name | |
79 | */ | |
80 | public List<Data> getData(String name) { | |
81 | List<Data> found = new LinkedList<Data>(); | |
82 | ||
26d2bd05 | 83 | for (Data data : this) { |
a3b510ab NR |
84 | if (data.getName().equals(name)) |
85 | found.add(data); | |
86 | } | |
87 | ||
88 | return found; | |
89 | } | |
90 | ||
91 | /** | |
92 | * Return a {@link String} representation of this contact. | |
93 | * | |
94 | * @param format | |
95 | * the {@link Format} to use | |
96 | * @param startingBKey | |
97 | * the starting BKey or -1 for no BKeys | |
98 | * @return the {@link String} representation | |
99 | */ | |
100 | public String toString(Format format, int startingBKey) { | |
101 | updateBKeys(false); | |
cf77cb35 NR |
102 | |
103 | StringBuilder builder = new StringBuilder(); | |
104 | for (String line : Parser.toStrings(this, format, startingBKey)) { | |
105 | builder.append(line); | |
106 | builder.append("\r\n"); | |
107 | } | |
108 | ||
109 | return builder.toString(); | |
a3b510ab NR |
110 | } |
111 | ||
0b0b2b0f NR |
112 | /** |
113 | * Return a {@link String} representation of this contact formated | |
114 | * accordingly to the given format. | |
115 | * | |
26d254a3 | 116 | * <p> |
0b0b2b0f | 117 | * The format is basically a list of field names separated by a pipe and |
30a4aa17 NR |
118 | * optionally parametrised with the 'at' (@) symbol. The parameters allows |
119 | * you to: | |
0b0b2b0f NR |
120 | * <ul> |
121 | * <li>@x: show only a present/not present info</li> | |
122 | * <li>@n: limit the size to a fixed value 'n'</li> | |
123 | * <li>@+: expand the size of this field as much as possible</li> | |
124 | * </ul> | |
26d254a3 | 125 | * </p> |
0b0b2b0f | 126 | * |
26d254a3 | 127 | * <p> |
30a4aa17 NR |
128 | * In case of lists or multiple-fields values, you can select a specific |
129 | * list or field with: | |
130 | * <ul> | |
131 | * <li>FIELD@(0): select the first value in a list</li> | |
132 | * <li>FIELD@[1]: select the second field in a multiple-fields value</li> | |
133 | * </ul> | |
134 | * </p> | |
135 | * | |
136 | * <p> | |
26d254a3 NR |
137 | * You can also add a fixed text if it starts with a simple-quote ('). |
138 | * </p> | |
139 | * | |
140 | * <p> | |
141 | * Example: "'Contact: |N@10|FN@20|NICK@+|PHOTO@x" | |
142 | * </p> | |
0b0b2b0f NR |
143 | * |
144 | * @param format | |
145 | * the format to use | |
26d254a3 NR |
146 | * @param separator |
147 | * the separator {@link String} to use between fields | |
0b0b2b0f NR |
148 | * |
149 | * @return the {@link String} representation | |
150 | */ | |
26d254a3 NR |
151 | public String toString(String format, String separator) { |
152 | return toString(format, separator, null, -1, true, false); | |
0b0b2b0f NR |
153 | } |
154 | ||
a3b510ab NR |
155 | /** |
156 | * Return a {@link String} representation of this contact formated | |
157 | * accordingly to the given format. | |
158 | * | |
26d254a3 | 159 | * <p> |
a3b510ab NR |
160 | * The format is basically a list of field names separated by a pipe and |
161 | * optionally parametrised. The parameters allows you to: | |
162 | * <ul> | |
26d254a3 | 163 | * <li>@x: show only a present/not present info</li> |
a3b510ab NR |
164 | * <li>@n: limit the size to a fixed value 'n'</li> |
165 | * <li>@+: expand the size of this field as much as possible</li> | |
166 | * </ul> | |
26d254a3 NR |
167 | * </p> |
168 | * | |
169 | * <p> | |
30a4aa17 NR |
170 | * In case of lists or multiple-fields values, you can select a specific |
171 | * list or field with: | |
172 | * <ul> | |
173 | * <li>FIELD@(0): select the first value in a list</li> | |
174 | * <li>FIELD@[1]: select the second field in a multiple-fields value</li> | |
175 | * </ul> | |
176 | * </p> | |
177 | * | |
178 | * <p> | |
26d254a3 NR |
179 | * You can also add a fixed text if it starts with a simple-quote ('). |
180 | * </p> | |
a3b510ab | 181 | * |
26d254a3 NR |
182 | * <p> |
183 | * Example: "'Contact: |N@10|FN@20|NICK@+|PHOTO@x" | |
184 | * </p> | |
a3b510ab NR |
185 | * |
186 | * @param format | |
187 | * the format to use | |
188 | * @param separator | |
189 | * the separator {@link String} to use between fields | |
0b0b2b0f NR |
190 | * @param padding |
191 | * the {@link String} to use for left and right padding | |
a3b510ab NR |
192 | * @param width |
193 | * a fixed width or -1 for "as long as needed" | |
194 | * | |
296a0b75 NR |
195 | * @param unicode |
196 | * allow Uniode or only ASCII characters | |
197 | * | |
a3b510ab NR |
198 | * @return the {@link String} representation |
199 | */ | |
0b0b2b0f | 200 | public String toString(String format, String separator, String padding, |
296a0b75 | 201 | int width, boolean unicode, boolean removeAccents) { |
9c8baf0c | 202 | StringBuilder builder = new StringBuilder(); |
a3b510ab | 203 | |
296a0b75 NR |
204 | for (String str : toStringArray(format, separator, padding, width, |
205 | unicode)) { | |
0b0b2b0f NR |
206 | builder.append(str); |
207 | } | |
a3b510ab | 208 | |
0b0b2b0f NR |
209 | return builder.toString(); |
210 | } | |
a3b510ab | 211 | |
0b0b2b0f NR |
212 | /** |
213 | * Return a {@link String} representation of this contact formated | |
214 | * accordingly to the given format, part by part. | |
215 | * | |
26d254a3 | 216 | * <p> |
0b0b2b0f NR |
217 | * The format is basically a list of field names separated by a pipe and |
218 | * optionally parametrised. The parameters allows you to: | |
219 | * <ul> | |
220 | * <li>@x: show only a present/not present info</li> | |
221 | * <li>@n: limit the size to a fixed value 'n'</li> | |
222 | * <li>@+: expand the size of this field as much as possible</li> | |
223 | * </ul> | |
26d254a3 | 224 | * </p> |
0b0b2b0f | 225 | * |
26d254a3 | 226 | * <p> |
30a4aa17 NR |
227 | * In case of lists or multiple-fields values, you can select a specific |
228 | * list or field with: | |
229 | * <ul> | |
230 | * <li>FIELD@(0): select the first value in a list</li> | |
231 | * <li>FIELD@[1]: select the second field in a multiple-fields value</li> | |
232 | * </ul> | |
233 | * </p> | |
234 | * | |
235 | * <p> | |
26d254a3 NR |
236 | * You can also add a fixed text if it starts with a simple-quote ('). |
237 | * </p> | |
238 | * | |
239 | * <p> | |
240 | * Example: "'Contact: |N@10|FN@20|NICK@+|PHOTO@x" | |
241 | * </p> | |
0b0b2b0f NR |
242 | * |
243 | * @param format | |
244 | * the format to use | |
245 | * @param separator | |
246 | * the separator {@link String} to use between fields | |
247 | * @param padding | |
248 | * the {@link String} to use for left and right padding | |
249 | * @param width | |
250 | * a fixed width or -1 for "as long as needed" | |
251 | * | |
296a0b75 NR |
252 | * @param unicode |
253 | * allow Uniode or only ASCII characters | |
254 | * | |
0b0b2b0f NR |
255 | * @return the {@link String} representation |
256 | */ | |
257 | public String[] toStringArray(String format, String separator, | |
296a0b75 | 258 | String padding, int width, boolean unicode) { |
0b0b2b0f NR |
259 | if (width > -1) { |
260 | int numOfFields = format.split("\\|").length; | |
261 | if (separator != null) | |
262 | width -= (numOfFields - 1) * separator.length(); | |
263 | if (padding != null) | |
264 | width -= (numOfFields) * (2 * padding.length()); | |
265 | ||
266 | if (width < 0) | |
267 | width = 0; | |
a3b510ab NR |
268 | } |
269 | ||
0b0b2b0f NR |
270 | List<String> str = new LinkedList<String>(); |
271 | ||
272 | boolean first = true; | |
296a0b75 | 273 | for (String s : toStringArray(format, width, unicode)) { |
0b0b2b0f NR |
274 | if (!first) { |
275 | str.add(separator); | |
276 | } | |
277 | ||
278 | if (padding != null) | |
279 | str.add(padding + s + padding); | |
280 | else | |
281 | str.add(s); | |
282 | ||
283 | first = false; | |
9c8baf0c NR |
284 | } |
285 | ||
0b0b2b0f | 286 | return str.toArray(new String[] {}); |
9c8baf0c NR |
287 | } |
288 | ||
289 | /** | |
290 | * Return a {@link String} representation of this contact formated | |
291 | * accordingly to the given format, part by part. | |
292 | * | |
26d254a3 | 293 | * <p> |
9c8baf0c | 294 | * The format is basically a list of field names separated by a pipe and |
0b0b2b0f NR |
295 | * optionally parametrised. The parameters allows you to: |
296 | * <ul> | |
297 | * <li>@x: show only a present/not present info</li> | |
298 | * <li>@n: limit the size to a fixed value 'n'</li> | |
299 | * <li>@+: expand the size of this field as much as possible</li> | |
300 | * </ul> | |
26d254a3 NR |
301 | * </p> |
302 | * | |
303 | * <p> | |
30a4aa17 NR |
304 | * In case of lists or multiple-fields values, you can select a specific |
305 | * list or field with: | |
306 | * <ul> | |
307 | * <li>FIELD@(0): select the first value in a list</li> | |
308 | * <li>FIELD@[1]: select the second field in a multiple-fields value</li> | |
309 | * </ul> | |
310 | * </p> | |
311 | * | |
312 | * <p> | |
26d254a3 NR |
313 | * You can also add a fixed text if it starts with a simple-quote ('). |
314 | * </p> | |
0b0b2b0f | 315 | * |
26d254a3 NR |
316 | * <p> |
317 | * Example: "'Contact: |N@10|FN@20|NICK@+|PHOTO@x" | |
318 | * </p> | |
9c8baf0c NR |
319 | * |
320 | * @param format | |
321 | * the format to use | |
322 | * @param width | |
323 | * a fixed width or -1 for "as long as needed" | |
296a0b75 NR |
324 | * @param unicode |
325 | * allow Uniode or only ASCII characters | |
326 | * | |
9c8baf0c NR |
327 | * @return the {@link String} representation |
328 | */ | |
296a0b75 | 329 | public String[] toStringArray(String format, int width, boolean unicode) { |
9c8baf0c NR |
330 | List<String> str = new LinkedList<String>(); |
331 | ||
332 | String[] formatFields = format.split("\\|"); | |
333 | String[] values = new String[formatFields.length]; | |
334 | Boolean[] expandedFields = new Boolean[formatFields.length]; | |
335 | Boolean[] fixedsizeFields = new Boolean[formatFields.length]; | |
336 | int numOfFieldsToExpand = 0; | |
337 | int totalSize = 0; | |
338 | ||
339 | if (width == 0) { | |
0b0b2b0f NR |
340 | for (int i = 0; i < formatFields.length; i++) { |
341 | str.add(""); | |
342 | } | |
bcb54330 | 343 | |
9c8baf0c NR |
344 | return str.toArray(new String[] {}); |
345 | } | |
346 | ||
a3b510ab NR |
347 | for (int i = 0; i < formatFields.length; i++) { |
348 | String field = formatFields[i]; | |
349 | ||
350 | int size = -1; | |
351 | boolean binary = false; | |
352 | boolean expand = false; | |
30a4aa17 NR |
353 | int fieldNum = -1; |
354 | int valueNum = -1; | |
a3b510ab | 355 | |
26d254a3 NR |
356 | if (field.length() > 0 && field.charAt(0) != '\'' |
357 | && field.contains("@")) { | |
a3b510ab NR |
358 | String[] opts = field.split("@"); |
359 | if (opts.length > 0) | |
360 | field = opts[0]; | |
361 | for (int io = 1; io < opts.length; io++) { | |
362 | String opt = opts[io]; | |
363 | if (opt.equals("x")) { | |
364 | binary = true; | |
365 | } else if (opt.equals("+")) { | |
366 | expand = true; | |
367 | numOfFieldsToExpand++; | |
30a4aa17 NR |
368 | } else if (opt.length() > 0 && opt.charAt(0) == '(') { |
369 | try { | |
370 | opt = opt.substring(1, opt.length() - 1); | |
371 | valueNum = Integer.parseInt(opt); | |
372 | } catch (Exception e) { | |
373 | } | |
374 | } else if (opt.length() > 0 && opt.charAt(0) == '[') { | |
375 | try { | |
376 | opt = opt.substring(1, opt.length() - 1); | |
377 | fieldNum = Integer.parseInt(opt); | |
378 | } catch (Exception e) { | |
379 | } | |
a3b510ab NR |
380 | } else { |
381 | try { | |
382 | size = Integer.parseInt(opt); | |
30a4aa17 | 383 | } catch (NumberFormatException e) { |
a3b510ab NR |
384 | } |
385 | } | |
386 | } | |
387 | } | |
388 | ||
26d254a3 NR |
389 | String value = null; |
390 | if (field.length() > 0 && field.charAt(0) == '\'') { | |
391 | value = field.substring(1); | |
30a4aa17 NR |
392 | } else if (valueNum >= 0) { |
393 | List<String> vv = getPreferredData(field).getValues(); | |
394 | if (valueNum < vv.size()) { | |
395 | value = vv.get(valueNum); | |
396 | } | |
397 | } else if (fieldNum >= 0) { | |
398 | List<String> ff = getPreferredData(field).getFields(); | |
399 | if (fieldNum < ff.size()) { | |
400 | value = ff.get(fieldNum); | |
401 | } | |
26d254a3 NR |
402 | } else { |
403 | value = getPreferredDataValue(field); | |
404 | } | |
405 | ||
296a0b75 | 406 | if (value == null) { |
a3b510ab | 407 | value = ""; |
296a0b75 NR |
408 | } else { |
409 | value = StringUtils.sanitize(value, unicode); | |
410 | } | |
a3b510ab NR |
411 | |
412 | if (size > -1) { | |
296a0b75 | 413 | value = StringUtils.padString(value, size); |
a3b510ab NR |
414 | } |
415 | ||
416 | expandedFields[i] = expand; | |
417 | fixedsizeFields[i] = (size > -1); | |
418 | ||
419 | if (binary) { | |
420 | if (value != null && !value.equals("")) | |
421 | values[i] = "x"; | |
422 | else | |
423 | values[i] = " "; | |
424 | totalSize++; | |
425 | } else { | |
426 | values[i] = value; | |
427 | totalSize += value.length(); | |
428 | } | |
429 | } | |
9c8baf0c | 430 | |
a3b510ab NR |
431 | if (width > -1 && totalSize > width) { |
432 | int toDo = totalSize - width; | |
433 | for (int i = fixedsizeFields.length - 1; toDo > 0 && i >= 0; i--) { | |
434 | if (!fixedsizeFields[i]) { | |
435 | int valueLength = values[i].length(); | |
436 | if (valueLength > 0) { | |
437 | if (valueLength >= toDo) { | |
438 | values[i] = values[i].substring(0, valueLength | |
439 | - toDo); | |
440 | toDo = 0; | |
441 | } else { | |
442 | values[i] = ""; | |
443 | toDo -= valueLength; | |
444 | } | |
445 | } | |
446 | } | |
447 | } | |
448 | ||
449 | totalSize = width + toDo; | |
450 | } | |
9c8baf0c | 451 | |
a3b510ab NR |
452 | if (width > -1 && numOfFieldsToExpand > 0) { |
453 | int availablePadding = width - totalSize; | |
454 | ||
455 | if (availablePadding > 0) { | |
456 | int padPerItem = availablePadding / numOfFieldsToExpand; | |
457 | int remainder = availablePadding % numOfFieldsToExpand; | |
458 | ||
459 | for (int i = 0; i < values.length; i++) { | |
460 | if (expandedFields[i]) { | |
461 | if (remainder > 0) { | |
296a0b75 NR |
462 | values[i] = values[i] |
463 | + StringUtils.padString("", remainder); | |
a3b510ab NR |
464 | remainder = 0; |
465 | } | |
466 | if (padPerItem > 0) { | |
296a0b75 NR |
467 | values[i] = values[i] |
468 | + StringUtils.padString("", padPerItem); | |
a3b510ab NR |
469 | } |
470 | } | |
471 | } | |
472 | ||
473 | totalSize = width; | |
474 | } | |
475 | } | |
a3b510ab | 476 | |
9c8baf0c NR |
477 | int currentSize = 0; |
478 | for (int i = 0; i < values.length; i++) { | |
479 | currentSize += addToList(str, values[i], currentSize, width); | |
a3b510ab NR |
480 | } |
481 | ||
9c8baf0c | 482 | return str.toArray(new String[] {}); |
a3b510ab NR |
483 | } |
484 | ||
a3b510ab NR |
485 | /** |
486 | * Update the information from this contact with the information in the | |
487 | * given contact. Non present fields will be removed, new fields will be | |
488 | * added, BKey'ed fields will be completed with the binary information known | |
489 | * by this contact. | |
490 | * | |
491 | * @param vc | |
492 | * the contact with the newer information and optional BKeys | |
493 | */ | |
494 | public void updateFrom(Contact vc) { | |
495 | updateBKeys(false); | |
496 | ||
26d2bd05 | 497 | List<Data> newDatas = new LinkedList<Data>(vc); |
a3b510ab NR |
498 | for (int i = 0; i < newDatas.size(); i++) { |
499 | Data data = newDatas.get(i); | |
500 | int bkey = Parser.getBKey(data); | |
501 | if (bkey >= 0) { | |
502 | if (binaries.containsKey(bkey)) { | |
503 | newDatas.set(i, binaries.get(bkey)); | |
504 | } | |
505 | } | |
506 | } | |
507 | ||
26d2bd05 | 508 | replaceListContent(newDatas); |
a3b510ab | 509 | this.nextBKey = vc.nextBKey; |
78e4af97 NR |
510 | } |
511 | ||
e253bd50 NR |
512 | @Override |
513 | public String getId() { | |
514 | return "" + getPreferredDataValue("UID"); | |
515 | } | |
516 | ||
517 | @Override | |
518 | public String getState() { | |
e4444b0b | 519 | return getId(); |
e253bd50 NR |
520 | } |
521 | ||
78e4af97 NR |
522 | /** |
523 | * Return a {@link String} representation of this contact, in vCard 2.1, | |
524 | * without BKeys. | |
525 | * | |
526 | * @return the {@link String} representation | |
527 | */ | |
528 | @Override | |
529 | public String toString() { | |
530 | return toString(Format.VCard21, -1); | |
531 | } | |
532 | ||
a3b510ab NR |
533 | /** |
534 | * Mark all the binary fields with a BKey number. | |
535 | * | |
536 | * @param force | |
537 | * force the marking, and reset all the numbers. | |
538 | */ | |
539 | protected void updateBKeys(boolean force) { | |
540 | if (force) { | |
541 | binaries = new HashMap<Integer, Data>(); | |
542 | nextBKey = 1; | |
543 | } | |
544 | ||
545 | if (binaries == null) { | |
546 | binaries = new HashMap<Integer, Data>(); | |
547 | } | |
548 | ||
26d2bd05 | 549 | for (Data data : this) { |
a3b510ab NR |
550 | if (data.isBinary() && (data.getB64Key() <= 0 || force)) { |
551 | binaries.put(nextBKey, data); | |
552 | data.resetB64Key(nextBKey++); | |
553 | } | |
554 | } | |
555 | } | |
556 | ||
a3b510ab | 557 | /** |
26d2bd05 NR |
558 | * Load the data from the given {@link File} under the given {@link Format}. |
559 | * | |
560 | * @param file | |
561 | * the {@link File} to load from | |
562 | * @param format | |
563 | * the {@link Format} to load as | |
564 | * | |
565 | * @return the list of elements | |
566 | * @throws IOException | |
567 | * in case of IO error | |
a3b510ab | 568 | */ |
26d2bd05 NR |
569 | static private List<Data> load(List<Data> content) { |
570 | List<Data> datas = new ArrayList<Data>(); | |
a3b510ab | 571 | |
26d2bd05 NR |
572 | boolean fn = false; |
573 | boolean n = false; | |
e253bd50 | 574 | boolean uid = false; |
26d2bd05 NR |
575 | if (content != null) { |
576 | for (Data data : content) { | |
577 | if (data.getName().equals("N")) { | |
578 | n = true; | |
579 | } else if (data.getName().equals("FN")) { | |
580 | fn = true; | |
e253bd50 NR |
581 | } else if (data.getName().equals("UID")) { |
582 | uid = true; | |
26d2bd05 NR |
583 | } |
584 | ||
585 | if (!data.getName().equals("VERSION")) { | |
586 | datas.add(data); | |
587 | } | |
588 | } | |
78e4af97 | 589 | } |
78e4af97 | 590 | |
26d2bd05 | 591 | // required fields: |
e253bd50 | 592 | if (!n) // required since vCard 3.0, supported in 2.1 |
26d2bd05 | 593 | datas.add(new Data(null, "N", "", null)); |
e253bd50 | 594 | if (!fn) // not required anymore but still supported in 4.0 |
26d2bd05 | 595 | datas.add(new Data(null, "FN", "", null)); |
e253bd50 NR |
596 | if (!uid) // supported by vCard, required by this program |
597 | datas.add(new Data(null, "UID", UUID.randomUUID().toString(), null)); | |
26d2bd05 NR |
598 | |
599 | return datas; | |
a3b510ab | 600 | } |
296a0b75 | 601 | |
bcb54330 | 602 | /** |
78e4af97 NR |
603 | * Add a {@link String} to the given {@link List}, but make sure it does not |
604 | * exceed the maximum size, and truncate it if needed to fit. | |
bcb54330 | 605 | * |
78e4af97 NR |
606 | * @param list |
607 | * @param add | |
608 | * @param currentSize | |
609 | * @param maxSize | |
610 | * @return | |
bcb54330 | 611 | */ |
78e4af97 NR |
612 | static private int addToList(List<String> list, String add, |
613 | int currentSize, int maxSize) { | |
614 | if (add == null || add.length() == 0) { | |
615 | if (add != null) | |
616 | list.add(add); | |
617 | return 0; | |
618 | } | |
619 | ||
620 | if (maxSize > -1) { | |
621 | if (currentSize < maxSize) { | |
622 | if (currentSize + add.length() >= maxSize) { | |
623 | add = add.substring(0, maxSize - currentSize); | |
bcb54330 | 624 | } |
78e4af97 NR |
625 | } else { |
626 | add = ""; | |
bcb54330 NR |
627 | } |
628 | } | |
629 | ||
78e4af97 NR |
630 | list.add(add); |
631 | return add.length(); | |
bcb54330 | 632 | } |
a3b510ab | 633 | } |