jdoc + some fixes
[jvcard.git] / src / be / nikiroo / jvcard / Card.java
CommitLineData
a3b510ab
NR
1package be.nikiroo.jvcard;
2
3import java.io.BufferedReader;
4import java.io.BufferedWriter;
5import java.io.File;
296a0b75 6import java.io.FileInputStream;
a3b510ab
NR
7import java.io.FileWriter;
8import java.io.IOException;
296a0b75 9import java.io.InputStreamReader;
78e4af97 10import java.security.InvalidParameterException;
a3b510ab
NR
11import java.util.Arrays;
12import java.util.LinkedList;
13import java.util.List;
14
15import be.nikiroo.jvcard.parsers.Format;
16import 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 */
25public 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}