Commit | Line | Data |
---|---|---|
a3b510ab NR |
1 | package be.nikiroo.jvcard; |
2 | ||
3 | import java.io.BufferedReader; | |
4 | import java.io.BufferedWriter; | |
5 | import java.io.File; | |
296a0b75 | 6 | import java.io.FileInputStream; |
a3b510ab NR |
7 | import java.io.FileWriter; |
8 | import java.io.IOException; | |
296a0b75 | 9 | import java.io.InputStreamReader; |
78e4af97 | 10 | import java.security.InvalidParameterException; |
a3b510ab NR |
11 | import java.util.Arrays; |
12 | import java.util.LinkedList; | |
13 | import java.util.List; | |
14 | ||
15 | import be.nikiroo.jvcard.parsers.Format; | |
16 | import be.nikiroo.jvcard.parsers.Parser; | |
17 | ||
18 | /** | |
19 | * A card is a contact information card. It contains data about one or more | |
20 | * contacts. | |
21 | * | |
22 | * @author niki | |
23 | * | |
24 | */ | |
25 | public class Card { | |
26 | private List<Contact> contacts; | |
27 | private File file; | |
28 | private boolean dirty; | |
0b0b2b0f | 29 | private String name; |
bcb54330 | 30 | private Format format; |
a3b510ab | 31 | |
78e4af97 NR |
32 | /** |
33 | * Create a new {@link Card} from the given {@link File} and {@link Format}. | |
34 | * | |
35 | * @param file | |
36 | * the file containing the {@link Card} data, must not be NULL | |
37 | * @param format | |
38 | * the {@link Format} to use to parse it | |
39 | * | |
40 | * @throws IOException | |
41 | * in case of IO error | |
42 | * @throws NullPointerException | |
43 | * if file is NULL | |
44 | * @throws InvalidParameterException | |
45 | * if format is NULL | |
46 | */ | |
a3b510ab NR |
47 | public Card(File file, Format format) throws IOException { |
48 | this.file = file; | |
bcb54330 | 49 | this.format = format; |
78e4af97 | 50 | this.name = file.getName(); |
0b0b2b0f | 51 | |
296a0b75 NR |
52 | BufferedReader buffer = new BufferedReader(new InputStreamReader( |
53 | new FileInputStream(file), "UTF-8")); | |
a3b510ab NR |
54 | List<String> lines = new LinkedList<String>(); |
55 | for (String line = buffer.readLine(); line != null; line = buffer | |
56 | .readLine()) { | |
57 | lines.add(line); | |
58 | } | |
bcb54330 | 59 | buffer.close(); |
a3b510ab NR |
60 | |
61 | load(lines, format); | |
bcb54330 NR |
62 | dirty = false; // initial load, so no change yet, so no need to call |
63 | // setPristine() | |
a3b510ab NR |
64 | } |
65 | ||
bcb54330 | 66 | /** |
78e4af97 | 67 | * Return the number of {@link Contact} present in this {@link Card}. |
bcb54330 | 68 | * |
78e4af97 | 69 | * @return the number of {@link Contact}s |
bcb54330 | 70 | */ |
78e4af97 NR |
71 | public int size() { |
72 | return contacts.size(); | |
a3b510ab NR |
73 | } |
74 | ||
bcb54330 | 75 | /** |
78e4af97 | 76 | * Return the {@link Contact} at index <i>index</i>. |
bcb54330 | 77 | * |
78e4af97 NR |
78 | * @param index |
79 | * the index of the {@link Contact} to find | |
80 | * | |
81 | * @return the {@link Contact} | |
82 | * | |
83 | * @throws IndexOutOfBoundsException | |
84 | * if the index is < 0 or >= {@link Card#size()} | |
bcb54330 | 85 | */ |
bcb54330 NR |
86 | public Contact get(int index) { |
87 | return contacts.get(index); | |
88 | } | |
89 | ||
78e4af97 NR |
90 | /** |
91 | * Save the {@link Card} to the given {@link File} with the given | |
92 | * {@link Format}. | |
93 | * | |
94 | * @param file | |
95 | * the {@link File} to save to | |
96 | * @param format | |
97 | * the {@link Format} to use | |
98 | * | |
99 | * @return TRUE if it was saved | |
100 | * | |
101 | * @throws IOException | |
102 | * in case of IO errors | |
103 | */ | |
a3b510ab NR |
104 | public boolean saveAs(File file, Format format) throws IOException { |
105 | if (file == null) | |
106 | return false; | |
107 | ||
108 | BufferedWriter writer = new BufferedWriter(new FileWriter(file)); | |
109 | writer.append(toString(format)); | |
110 | writer.close(); | |
111 | ||
112 | if (file.equals(this.file)) { | |
bcb54330 | 113 | setPristine(); |
a3b510ab NR |
114 | } |
115 | ||
116 | return true; | |
117 | } | |
118 | ||
78e4af97 NR |
119 | /** |
120 | * Save the {@link Card} to the original {@link File} it was open from. | |
121 | * | |
122 | * @return TRUE if it was saved | |
123 | * | |
124 | * @throws IOException | |
125 | * in case of IO errors | |
126 | */ | |
bcb54330 | 127 | public boolean save() throws IOException { |
a3b510ab NR |
128 | return saveAs(file, format); |
129 | } | |
130 | ||
78e4af97 NR |
131 | /** |
132 | * Return a {@link String} representation of this {@link Card} in the given | |
133 | * {@link Format}. | |
134 | * | |
135 | * @param format | |
136 | * the {@link Format} to use | |
137 | * | |
138 | * @return the {@link String} | |
139 | */ | |
a3b510ab NR |
140 | public String toString(Format format) { |
141 | return Parser.toString(this, format); | |
142 | } | |
143 | ||
78e4af97 NR |
144 | /** |
145 | * Check if this {@link Card} has unsaved changes. | |
146 | * | |
147 | * @return TRUE if it has | |
148 | */ | |
149 | public boolean isDirty() { | |
150 | return dirty; | |
151 | } | |
152 | ||
153 | /** | |
154 | * Return the name of this card (the name of the {@link File} which it was | |
155 | * opened from). | |
156 | * | |
157 | * @return the name | |
158 | */ | |
159 | public String getName() { | |
160 | return name; | |
161 | } | |
162 | ||
163 | @Override | |
a3b510ab NR |
164 | public String toString() { |
165 | return toString(Format.VCard21); | |
166 | } | |
167 | ||
78e4af97 NR |
168 | /** |
169 | * Load the given data from the given {@link Format} in this {@link Card}. | |
170 | * | |
171 | * @param serializedContent | |
172 | * the data | |
173 | * @param format | |
174 | * the {@link Format} | |
175 | */ | |
a3b510ab NR |
176 | protected void load(String serializedContent, Format format) { |
177 | // note: fixed size array | |
178 | List<String> lines = Arrays.asList(serializedContent.split("\n")); | |
179 | load(lines, format); | |
180 | } | |
181 | ||
78e4af97 NR |
182 | /** |
183 | * Load the given data from the given {@link Format} in this {@link Card}. | |
184 | * | |
185 | * @param lines | |
186 | * the data | |
187 | * @param format | |
188 | * the {@link Format} | |
189 | */ | |
a3b510ab NR |
190 | protected void load(List<String> lines, Format format) { |
191 | this.contacts = Parser.parse(lines, format); | |
192 | setDirty(); | |
193 | ||
194 | for (Contact contact : contacts) { | |
195 | contact.setParent(this); | |
196 | } | |
197 | } | |
198 | ||
0b0b2b0f | 199 | /** |
78e4af97 NR |
200 | * Return the full list of {@link Contact}s. Please use responsibly (this is |
201 | * the original list). | |
0b0b2b0f | 202 | * |
78e4af97 | 203 | * @return the list of {@link Contact}s |
0b0b2b0f | 204 | */ |
78e4af97 NR |
205 | List<Contact> getContactsList() { |
206 | return contacts; | |
0b0b2b0f NR |
207 | } |
208 | ||
a3b510ab NR |
209 | /** |
210 | * Notify that this element has unsaved changes. | |
211 | */ | |
212 | void setDirty() { | |
213 | dirty = true; | |
214 | } | |
bcb54330 NR |
215 | |
216 | /** | |
217 | * Notify this element <i>and all its descendants</i> that it is in pristine | |
218 | * state (as opposed to dirty). | |
219 | */ | |
220 | void setPristine() { | |
221 | dirty = false; | |
222 | for (Contact contact : contacts) { | |
223 | contact.setPristine(); | |
224 | } | |
225 | } | |
a3b510ab | 226 | } |