f2bb4080f6d770776e1824e0cf7cfd7495c20433
[jvcard.git] / src / be / nikiroo / jvcard / Data.java
1 package be.nikiroo.jvcard;
2
3 import java.security.InvalidParameterException;
4 import java.util.LinkedList;
5 import java.util.List;
6
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 */
14 public class Data {
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
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
27 private List<TypeInfo> types;
28 private boolean dirty;
29 private Contact parent;
30
31 /**
32 * Create a new {@link Data} with the given values.
33 *
34 * @param types
35 * the types of this {@link Data}
36 * @param name
37 * its name
38 * @param value
39 * its value
40 * @param group
41 * its group if any
42 */
43 public Data(List<TypeInfo> types, String name, String value, String group) {
44 if (types == null) {
45 types = new LinkedList<TypeInfo>();
46 }
47
48 this.types = types;
49 this.name = name;
50 this.value = value;
51 this.group = group;
52
53 b64 = -1;
54 for (TypeInfo type : types) {
55 type.setParent(this);
56 if (type.getName().equals("ENCODING")
57 && type.getValue().equals("b")) {
58 b64 = 0;
59 break;
60 }
61 }
62 }
63
64 /**
65 * Return the number of {@link TypeInfo} present in this {@link Data}.
66 *
67 * @return the number of {@link TypeInfo}s
68 */
69 public int size() {
70 return types.size();
71 }
72
73 /**
74 * Return the {@link TypeInfo} at index <i>index</i>.
75 *
76 * @param index
77 * the index of the {@link TypeInfo} to find
78 *
79 * @return the {@link TypeInfo}
80 *
81 * @throws IndexOutOfBoundsException
82 * if the index is < 0 or >= {@link Data#size()}
83 */
84 public TypeInfo get(int index) {
85 return types.get(index);
86 }
87
88 /**
89 * Return the name of this {@link Data}
90 *
91 * @return the name
92 */
93 public String getName() {
94 return name;
95 }
96
97 /**
98 * Return the value of this {@link Data}
99 *
100 * @return the value
101 */
102 public String getValue() {
103 return value;
104 }
105
106 /**
107 * Change the value of this {@link Data}
108 *
109 * @param value
110 * the new value
111 */
112 public void setValue(String value) {
113 if ((value == null && this.value != null)
114 || (value != null && !value.equals(this.value))) {
115 this.value = value;
116 setDirty();
117 }
118 }
119
120 /**
121 * Return the group of this {@link Data}
122 *
123 * @return the group
124 */
125 public String getGroup() {
126 return group;
127 }
128
129 /**
130 * Return the bkey number of this {@link Data} or -1 if it is not binary.
131 *
132 * @return the bkey or -1
133 */
134 public int getB64Key() {
135 return b64;
136 }
137
138 /**
139 * Change the bkey of this {@link Data}
140 *
141 * @param i
142 * the new bkey
143 *
144 * @throw InvalidParameterException if the {@link Data} is not binary or if
145 * it is but you try to set a negative bkey
146 */
147 void resetB64Key(int i) {
148 if (!isBinary())
149 throw new InvalidParameterException(
150 "Cannot add a BKey on a non-binary object");
151 if (i < 0)
152 throw new InvalidParameterException(
153 "Cannot remove the BKey on a binary object");
154
155 b64 = i;
156 }
157
158 /**
159 * Check if this {@link Data} is binary
160 *
161 * @return TRUE if it is
162 */
163 public boolean isBinary() {
164 return b64 >= 0;
165 }
166
167 /**
168 * Check if this {@link Data} has unsaved changes.
169 *
170 * @return TRUE if it has
171 */
172 public boolean isDirty() {
173 return dirty;
174 }
175
176 /**
177 * Notify that this element has unsaved changes, and notify its parent of
178 * the same if any.
179 */
180 protected void setDirty() {
181 this.dirty = true;
182 if (this.parent != null)
183 this.parent.setDirty();
184 }
185
186 /**
187 * Notify this element <i>and all its descendants</i> that it is in pristine
188 * state (as opposed to dirty).
189 */
190 void setPristine() {
191 dirty = false;
192 for (TypeInfo type : types) {
193 type.setPristine();
194 }
195 }
196
197 /**
198 * Set the parent of this {@link Data}.
199 *
200 * @param parent
201 * the new parent
202 */
203 void setParent(Contact parent) {
204 this.parent = parent;
205 }
206 }