Some fixes (crash when adding raw "x=" field, "dirty" handling)
[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.LinkedList;
12import java.util.List;
13
14import be.nikiroo.jvcard.parsers.Format;
15import be.nikiroo.jvcard.parsers.Parser;
16
17/**
18 * A card is a contact information card. It contains data about one or more
19 * contacts.
20 *
21 * @author niki
22 *
23 */
26d2bd05 24public class Card extends BaseClass<Contact> {
a3b510ab 25 private File file;
0b0b2b0f 26 private String name;
bcb54330 27 private Format format;
b9f192ed
NR
28 private long lastModified;
29 private boolean remote;
a3b510ab 30
78e4af97
NR
31 /**
32 * Create a new {@link Card} from the given {@link File} and {@link Format}.
33 *
34 * @param file
b9f192ed
NR
35 * the input {@link File} containing the {@link Card} data or
36 * NULL for an empty card (usually a {@link File} name or a
37 * network path)
78e4af97
NR
38 * @param format
39 * the {@link Format} to use to parse it
40 *
41 * @throws IOException
42 * in case of IO error
78e4af97
NR
43 * @throws InvalidParameterException
44 * if format is NULL
45 */
a3b510ab 46 public Card(File file, Format format) throws IOException {
b9f192ed
NR
47 this(load(file, format));
48
49 if (file != null) {
50 if (file.exists()) {
51 lastModified = file.lastModified();
52 }
53 }
26d2bd05 54
bcb54330 55 this.format = format;
b9f192ed
NR
56
57 if (file != null) {
58 this.file = file;
59 switch (format) {
60 case VCard21:
61 this.name = file.getName().replaceAll(
62 ".[vV][cC][fF]$", "");
63 break;
64 case Abook:
65 default:
66 this.name = file.getName();
67 break;
68 }
69 }
70 }
71
72 /**
73 * Create a new {@link Card} from the given {@link Contact}s.
74 *
75 * @param contacts
76 * the input contacts
77 *
78 * @throws IOException
79 * in case of IO error
80 * @throws InvalidParameterException
81 * if format is NULL
82 */
83 public Card(List<Contact> contacts) throws IOException {
84 super(contacts);
85
86 lastModified = -1;
176a8327 87 }
bcb54330 88
78e4af97
NR
89 /**
90 * Save the {@link Card} to the given {@link File} with the given
91 * {@link Format}.
92 *
b9f192ed
NR
93 * @param output
94 * the output to save to
78e4af97
NR
95 * @param format
96 * the {@link Format} to use
97 *
98 * @return TRUE if it was saved
99 *
100 * @throws IOException
101 * in case of IO errors
102 */
b9f192ed
NR
103 public boolean saveAs(File output, Format format) throws IOException {
104 if (output == null)
a3b510ab
NR
105 return false;
106
b9f192ed 107 BufferedWriter writer = new BufferedWriter(new FileWriter(output));
a3b510ab
NR
108 writer.append(toString(format));
109 writer.close();
110
b9f192ed 111 if (output.getCanonicalPath().equals(this.file.getCanonicalPath())) {
bcb54330 112 setPristine();
a3b510ab
NR
113 }
114
115 return true;
116 }
117
78e4af97
NR
118 /**
119 * Save the {@link Card} to the original {@link File} it was open from.
120 *
121 * @return TRUE if it was saved
122 *
123 * @throws IOException
124 * in case of IO errors
125 */
bcb54330 126 public boolean save() throws IOException {
a3b510ab
NR
127 return saveAs(file, format);
128 }
129
b9f192ed
NR
130 /**
131 * Reload the data from the input.
132 *
133 * @return TRUE if it was done
134 *
135 * @throws IOException
136 * in case of IO error
137 */
138 public boolean reload() throws IOException {
139 if (file == null)
140 return false;
141
142 this.replaceListContent(load(file, format));
143 setPristine();
144 return true;
145 }
146
78e4af97
NR
147 /**
148 * Return a {@link String} representation of this {@link Card} in the given
149 * {@link Format}.
150 *
151 * @param format
152 * the {@link Format} to use
153 *
154 * @return the {@link String}
155 */
a3b510ab
NR
156 public String toString(Format format) {
157 return Parser.toString(this, format);
158 }
159
78e4af97
NR
160 /**
161 * Return the name of this card (the name of the {@link File} which it was
162 * opened from).
163 *
164 * @return the name
165 */
166 public String getName() {
167 return name;
168 }
169
b9f192ed
NR
170 /**
171 * Return the original {@link Format} of the {@link Card}.
172 *
173 * @return the {@link Format}
174 */
175 public Format getFormat() {
176 return format;
177 }
178
179 /**
180 * Return the input which was used to open this {@link Card}.
181 *
182 * @return the input
183 */
184 public File getInput() {
185 return file;
186 }
187
188 /**
189 * Return the date of the last modification for this {@link Card} (or -1 if
190 * unknown/new).
191 *
192 * @return the last modified date
193 */
194 public long getLastModified() {
195 return lastModified;
196 }
197
198 /**
199 * Check if this {@link Card} is remote.
200 *
201 * @return TRUE if this {@link Card} is remote
202 */
203 public boolean isRemote() {
204 return remote;
205 }
206
207 /**
208 * Set the remote option on this {@link Card}.
209 *
210 * @param remote
211 * TRUE if this {@link Card} is remote
212 */
213 public void setRemote(boolean remote) {
214 this.remote = remote;
215 }
216
78e4af97 217 @Override
a3b510ab
NR
218 public String toString() {
219 return toString(Format.VCard21);
220 }
221
78e4af97 222 /**
26d2bd05 223 * Load the data from the given {@link File} under the given {@link Format}.
78e4af97 224 *
26d2bd05 225 * @param file
b9f192ed 226 * the input to load from
78e4af97 227 * @param format
26d2bd05 228 * the {@link Format} to load as
78e4af97 229 *
26d2bd05 230 * @return the list of elements
b9f192ed 231 *
26d2bd05
NR
232 * @throws IOException
233 * in case of IO error
78e4af97 234 */
b9f192ed 235 private static List<Contact> load(File file, Format format)
26d2bd05 236 throws IOException {
b9f192ed
NR
237 List<String> lines = null;
238
239 if (file != null && file.exists()) {
240 BufferedReader buffer = new BufferedReader(new InputStreamReader(
241 new FileInputStream(file), "UTF-8"));
242 lines = new LinkedList<String>();
243 for (String line = buffer.readLine(); line != null; line = buffer
244 .readLine()) {
245 lines.add(line);
246 }
247 buffer.close();
a3b510ab 248 }
b9f192ed
NR
249
250 if (lines == null)
251 return new LinkedList<Contact>();
bcb54330 252
26d2bd05 253 return Parser.parse(lines, format);
bcb54330 254 }
a3b510ab 255}