package be.nikiroo.jvcard;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import be.nikiroo.jvcard.parsers.Format;
import be.nikiroo.jvcard.parsers.Parser;
* @author niki
*
*/
-public class Contact {
- private List<Data> datas;
+public class Contact extends BaseClass<Data> {
private int nextBKey = 1;
private Map<Integer, Data> binaries;
- private boolean dirty;
- private Card parent;
/**
* Create a new Contact from the given information. Note that the BKeys data
* the information about the contact
*/
public Contact(List<Data> content) {
- this.datas = new LinkedList<Data>();
-
- boolean fn = false;
- boolean n = false;
- for (Data data : content) {
- if (data.getName().equals("N")) {
- n = true;
- } else if (data.getName().equals("FN")) {
- fn = true;
- }
-
- if (!data.getName().equals("VERSION")) {
- datas.add(data);
- }
- }
-
- // required fields:
- if (!n) {
- datas.add(new Data(null, "N", "", null));
- }
- if (!fn) {
- datas.add(new Data(null, "FN", "", null));
- }
-
+ super(load(content));
updateBKeys(true);
}
- /**
- * Return the number of {@link Data} present in this {@link Contact}.
- *
- * @return the number of {@link Data}s
- */
- public int size() {
- return datas.size();
- }
-
- /**
- * Return the {@link Data} at index <i>index</i>.
- *
- * @param index
- * the index of the {@link Data} to find
- *
- * @return the {@link Data}
- *
- * @throws IndexOutOfBoundsException
- * if the index is < 0 or >= {@link Contact#size()}
- */
- public Data get(int index) {
- return datas.get(index);
- }
-
/**
* Return the preferred Data field with the given name, or NULL if none.
*
public List<Data> getData(String name) {
List<Data> found = new LinkedList<Data>();
- for (Data data : datas) {
+ for (Data data : this) {
if (data.getName().equals(name))
found.add(data);
}
* The format is basically a list of field names separated by a pipe and
* optionally parametrised. The parameters allows you to:
* <ul>
- * <li>@x: show only a present/not present info</li>
+ * <li>@x: (the 'x' is the letter 'x') show only a present/not present info</li>
* <li>@n: limit the size to a fixed value 'n'</li>
* <li>@+: expand the size of this field as much as possible</li>
* </ul>
public void updateFrom(Contact vc) {
updateBKeys(false);
- List<Data> newDatas = new LinkedList<Data>(vc.datas);
+ List<Data> newDatas = new LinkedList<Data>(vc);
for (int i = 0; i < newDatas.size(); i++) {
Data data = newDatas.get(i);
int bkey = Parser.getBKey(data);
}
}
- this.datas = newDatas;
+ replaceListContent(newDatas);
this.nextBKey = vc.nextBKey;
-
- setParent(parent);
- setDirty();
}
- /**
- * Delete this {@link Contact} from its parent {@link Card} if any.
- *
- * @return TRUE in case of success
- */
- public boolean delete() {
- if (parent != null) {
- List<Contact> list = parent.getContactsList();
- for (int i = 0; i < list.size(); i++) {
- if (list.get(i) == this) {
- list.remove(i);
- parent.setDirty();
- return true;
- }
- }
- }
-
- return false;
+ @Override
+ public String getId() {
+ return "" + getPreferredDataValue("UID");
}
- /**
- * Check if this {@link Contact} has unsaved changes.
- *
- * @return TRUE if it has
- */
- public boolean isDirty() {
- return dirty;
+ @Override
+ public String getState() {
+ return "" + getPreferredDataValue("UID");
}
/**
binaries = new HashMap<Integer, Data>();
}
- for (Data data : datas) {
+ for (Data data : this) {
if (data.isBinary() && (data.getB64Key() <= 0 || force)) {
binaries.put(nextBKey, data);
data.resetB64Key(nextBKey++);
}
/**
- * Notify that this element has unsaved changes, and notify its parent of
- * the same if any.
+ * Load the data from the given {@link File} under the given {@link Format}.
+ *
+ * @param file
+ * the {@link File} to load from
+ * @param format
+ * the {@link Format} to load as
+ *
+ * @return the list of elements
+ * @throws IOException
+ * in case of IO error
*/
- protected void setDirty() {
- this.dirty = true;
- if (this.parent != null)
- this.parent.setDirty();
- }
+ static private List<Data> load(List<Data> content) {
+ List<Data> datas = new ArrayList<Data>();
- /**
- * Notify this element <i>and all its descendants</i> that it is in pristine
- * state (as opposed to dirty).
- */
- void setPristine() {
- dirty = false;
- for (Data data : datas) {
- data.setPristine();
- }
- }
+ boolean fn = false;
+ boolean n = false;
+ boolean uid = false;
+ if (content != null) {
+ for (Data data : content) {
+ if (data.getName().equals("N")) {
+ n = true;
+ } else if (data.getName().equals("FN")) {
+ fn = true;
+ } else if (data.getName().equals("UID")) {
+ uid = true;
+ }
- /**
- * Set the parent of this {@link Contact} <i>and all its descendants</i>.
- *
- * @param parent
- * the new parent
- */
- void setParent(Card parent) {
- this.parent = parent;
- for (Data data : datas) {
- data.setParent(this);
+ if (!data.getName().equals("VERSION")) {
+ datas.add(data);
+ }
+ }
}
+
+ // required fields:
+ if (!n) // required since vCard 3.0, supported in 2.1
+ datas.add(new Data(null, "N", "", null));
+ if (!fn) // not required anymore but still supported in 4.0
+ datas.add(new Data(null, "FN", "", null));
+ if (!uid) // supported by vCard, required by this program
+ datas.add(new Data(null, "UID", UUID.randomUUID().toString(), null));
+
+ return datas;
}
/**
list.add(add);
return add.length();
}
-
}