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