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.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 | */ | |
26d2bd05 | 24 | public 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 | } |