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