package be.nikiroo.jvcard;
-import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.security.InvalidParameterException;
-import java.util.Arrays;
-import java.util.LinkedList;
import java.util.List;
import be.nikiroo.jvcard.parsers.Format;
* @author niki
*
*/
-public class Card {
- private List<Contact> contacts;
+public class Card extends BaseClass<Contact> {
private File file;
- private boolean dirty;
private String name;
private Format format;
+ private long lastModified;
+ private boolean remote;
/**
* Create a new {@link Card} from the given {@link File} and {@link Format}.
*
* @param file
- * the file containing the {@link Card} data, must not be NULL
+ * the input {@link File} containing the {@link Card} data or
+ * NULL for an empty card (usually a {@link File} name or a
+ * network path)
* @param format
* the {@link Format} to use to parse it
*
* @throws IOException
* in case of IO error
- * @throws NullPointerException
- * if file is NULL
* @throws InvalidParameterException
* if format is NULL
*/
public Card(File file, Format format) throws IOException {
- this.file = file;
- this.format = format;
- this.name = file.getName();
-
- BufferedReader buffer = new BufferedReader(new InputStreamReader(
- new FileInputStream(file), "UTF-8"));
- List<String> lines = new LinkedList<String>();
- for (String line = buffer.readLine(); line != null; line = buffer
- .readLine()) {
- lines.add(line);
+ this(Parser.parse(file, format));
+
+ if (file != null) {
+ if (file.exists()) {
+ lastModified = file.lastModified();
+ }
}
- buffer.close();
- load(lines, format);
- dirty = false; // initial load, so no change yet, so no need to call
- // setPristine()
- }
+ this.format = format;
- /**
- * Return the number of {@link Contact} present in this {@link Card}.
- *
- * @return the number of {@link Contact}s
- */
- public int size() {
- return contacts.size();
+ if (file != null) {
+ this.file = file;
+ switch (format) {
+ case VCard21:
+ this.name = file.getName().replaceAll(".[vV][cC][fF]$", "");
+ break;
+ case Abook:
+ default:
+ this.name = file.getName();
+ break;
+ }
+ }
}
/**
- * Return the {@link Contact} at index <i>index</i>.
+ * Create a new {@link Card} from the given {@link Contact}s.
*
- * @param index
- * the index of the {@link Contact} to find
- *
- * @return the {@link Contact}
- *
- * @throws IndexOutOfBoundsException
- * if the index is < 0 or >= {@link Card#size()}
- */
- public Contact get(int index) {
- return contacts.get(index);
- }
-
- /**
- * Add a new {@link Contact} in this {@link Card}.
- *
- * @param contact
- * the new contact
- */
- public void add(Contact contact) {
- contact.setParent(this);
- contact.setDirty();
- contacts.add(contact);
- }
-
- /**
- * Remove the given {@link Contact} from its this {@link Card} if it is in.
+ * @param contacts
+ * the input contacts
*
- * @return TRUE in case of success
+ * @throws IOException
+ * in case of IO error
+ * @throws InvalidParameterException
+ * if format is NULL
*/
- public boolean remove(Contact contact) {
- if (contacts.remove(contact)) {
- setDirty();
- }
+ public Card(List<Contact> contacts) throws IOException {
+ super(contacts);
- return false;
+ lastModified = -1;
}
/**
* {@link Format}.
*
* @param file
- * the {@link File} to save to
+ * the output to save to
* @param format
* the {@link Format} to use
*
writer.append(toString(format));
writer.close();
- if (file.equals(this.file)) {
+ if (this.file != null
+ && file.getCanonicalPath().equals(this.file.getCanonicalPath())) {
setPristine();
}
return saveAs(file, format);
}
+ /**
+ * Reload the data from the input.
+ *
+ * @return TRUE if it was done
+ *
+ * @throws IOException
+ * in case of IO error
+ */
+ public boolean reload() throws IOException {
+ if (file == null)
+ return false;
+
+ this.replaceListContent(Parser.parse(file, format));
+ setPristine();
+ return true;
+ }
+
/**
* Return a {@link String} representation of this {@link Card} in the given
* {@link Format}.
return Parser.toString(this, format);
}
- /**
- * Check if this {@link Card} has unsaved changes.
- *
- * @return TRUE if it has
- */
- public boolean isDirty() {
- return dirty;
- }
-
/**
* Return the name of this card (the name of the {@link File} which it was
* opened from).
return name;
}
- @Override
- public String toString() {
- return toString(Format.VCard21);
+ /**
+ * Return the original {@link Format} of the {@link Card}.
+ *
+ * @return the {@link Format}
+ */
+ public Format getFormat() {
+ return format;
}
/**
- * Load the given data from the given {@link Format} in this {@link Card}.
+ * Return the {@link File} which was used to open this {@link Card}.
*
- * @param serializedContent
- * the data
- * @param format
- * the {@link Format}
+ * @return the input
*/
- protected void load(String serializedContent, Format format) {
- // note: fixed size array
- List<String> lines = Arrays.asList(serializedContent.split("\n"));
- load(lines, format);
+ public File getFile() {
+ return file;
}
/**
- * Load the given data from the given {@link Format} in this {@link Card}.
+ * Return the date of the last modification for this {@link Card} (or -1 if
+ * unknown/new).
*
- * @param lines
- * the data
- * @param format
- * the {@link Format}
+ * @return the last modified date
*/
- protected void load(List<String> lines, Format format) {
- this.contacts = Parser.parse(lines, format);
- setDirty();
-
- for (Contact contact : contacts) {
- contact.setParent(this);
- }
+ public long getLastModified() {
+ return lastModified;
}
/**
- * Notify that this element has unsaved changes.
+ * Check if this {@link Card} is remote.
+ *
+ * @return TRUE if this {@link Card} is remote
*/
- void setDirty() {
- dirty = true;
+ public boolean isRemote() {
+ return remote;
}
/**
- * Notify this element <i>and all its descendants</i> that it is in pristine
- * state (as opposed to dirty).
+ * Set the remote option on this {@link Card}.
+ *
+ * @param remote
+ * TRUE if this {@link Card} is remote
*/
- void setPristine() {
- dirty = false;
- for (Contact contact : contacts) {
- contact.setPristine();
- }
+ public void setRemote(boolean remote) {
+ this.remote = remote;
+ }
+
+ @Override
+ public String toString() {
+ return toString(Format.VCard21);
+ }
+
+ @Override
+ public String getId() {
+ return "" + name;
+ }
+
+ @Override
+ public String getState() {
+ return "" + name + format;
}
}