* @author niki
*
*/
-public class Data {
+public class Data extends BaseClass<TypeInfo> {
public enum DataPart {
FN_FAMILY, FN_GIVEN, FN_ADDITIONAL, // Name
FN_PRE, FN_POST, // Pre/Post
private String value;
private String group;
private int b64; // -1 = no, 0 = still not ordered, the rest is order
- private List<TypeInfo> types;
- private boolean dirty;
- private Contact parent;
/**
* Create a new {@link Data} with the given values.
* @param types
* the types of this {@link Data}
* @param name
- * its name
+ * its name (<b>MUST NOT</b> be NULL)
* @param value
- * its value
+ * its value (<b>MUST NOT</b> be NULL)
* @param group
- * its group if any
+ * its group if any (or NULL if none)
*/
public Data(List<TypeInfo> types, String name, String value, String group) {
- if (types == null) {
- types = new LinkedList<TypeInfo>();
- }
+ super(types);
- this.types = types;
- this.name = name;
- this.value = value;
+ this.name = name.toUpperCase();
+ this.value = value.toString(); // crash NOW if null
this.group = group;
b64 = -1;
- for (TypeInfo type : types) {
- type.setParent(this);
+ for (TypeInfo type : this) {
if (type.getName().equals("ENCODING")
&& type.getValue().equals("b")) {
b64 = 0;
}
/**
- * Return the number of {@link TypeInfo} present in this {@link Data}.
+ * Return the name of this {@link Data}
*
- * @return the number of {@link TypeInfo}s
+ * @return the name
*/
- public int size() {
- return types.size();
+ public String getName() {
+ return name;
}
/**
- * Return the {@link TypeInfo} at index <i>index</i>.
- *
- * @param index
- * the index of the {@link TypeInfo} to find
- *
- * @return the {@link TypeInfo}
+ * Return the value of this {@link Data}
*
- * @throws IndexOutOfBoundsException
- * if the index is < 0 or >= {@link Data#size()}
+ * @return the value
*/
- public TypeInfo get(int index) {
- return types.get(index);
+ public String getValue() {
+ return unescape(value);
}
/**
- * Return the name of this {@link Data}
+ * Change the value of this {@link Data}
*
- * @return the name
+ * @param value
+ * the new value
*/
- public String getName() {
- return name;
+ public void setValue(String value) {
+ setRawValue(escape(value));
}
/**
- * Return the value of this {@link Data}
+ * Return the raw value of this {@link Data}
*
- * @return the value
+ * @return the raw value
*/
- public String getValue() {
+ public String getRawValue() {
return value;
}
/**
- * Change the value of this {@link Data}
+ * Change the raw value of this {@link Data}
*
* @param value
- * the new value
+ * the new raw value
*/
- public void setValue(String value) {
+ public void setRawValue(String value) {
if ((value == null && this.value != null)
|| (value != null && !value.equals(this.value))) {
this.value = value;
}
}
+ /**
+ * Return the {@link List} of comma-listed values from this {@link Data}.
+ *
+ * @return the {@link List} of values
+ */
+ public List<String> getValues() {
+ return getList(',');
+ }
+
+ /**
+ * Set the {@link List} of comma-listed values from this {@link Data}.
+ *
+ * @param values
+ * the {@link List} of values
+ */
+ public void setValues(List<String> values) {
+ setList(values, ',');
+ }
+
+ /**
+ * Return the {@link List} of semi-column-listed fields from this
+ * {@link Data}.
+ *
+ * @return the {@link List} of values
+ */
+ public List<String> getFields() {
+ return getList(';');
+ }
+
+ /**
+ * Set the {@link List} of comma-listed values from this {@link Data}.
+ *
+ * @param values
+ * the {@link List} of values
+ */
+ public void setFields(List<String> values) {
+ setList(values, ';');
+ }
+
/**
* Return the group of this {@link Data}
*
return group;
}
+ /**
+ * Change the group of this {@link Data}
+ *
+ * @param group
+ * the new group
+ */
+ public void setGroup(String group) {
+ if ((group == null && this.group != null)
+ || (group != null && !group.equals(this.group))) {
+ this.group = group;
+ setDirty();
+ }
+ }
+
/**
* Return the bkey number of this {@link Data} or -1 if it is not binary.
*
return b64;
}
+ /**
+ * Check if this {@link Data} is binary
+ *
+ * @return TRUE if it is
+ */
+ public boolean isBinary() {
+ return b64 >= 0;
+ }
+
+ /**
+ * Check if this {@link Data} has the "preferred" flag.
+ *
+ * @return TRUE if it has
+ */
+ public boolean isPreferred() {
+ for (TypeInfo type : this) {
+ if (type.getName().equals("TYPE") && type.getValue().equals("pref")) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/**
* Change the bkey of this {@link Data}
*
}
/**
- * Check if this {@link Data} is binary
+ * Return the {@link List} of sep-listed values from this {@link String}
+ * data.
*
- * @return TRUE if it is
+ * @param value
+ * the data
+ *
+ * @param the
+ * separator
+ *
+ * @return the {@link List} of values
*/
- public boolean isBinary() {
- return b64 >= 0;
+ private List<String> getList(char sep) {
+ List<String> rep = new LinkedList<String>();
+
+ if (value != null && value.length() > 0) {
+ int last = 0;
+ for (int i = 0; i < value.length(); i++) {
+ if (value.charAt(i) == sep
+ && (i == 0 || value.charAt(i - 1) != '\\')) {
+ rep.add(value.substring(last, i));
+ last = i + 1;
+ }
+ }
+
+ if (last < value.length())
+ rep.add(value.substring(last));
+ }
+
+ return rep;
}
/**
- * Check if this {@link Data} has unsaved changes.
+ * Create the {@link String}-encoded {@link List} of sep-listed values from
+ * the given values.
*
- * @return TRUE if it has
+ * @param values
+ * the {@link List} of values
+ *
+ * @param sep
+ * the separator
+ *
+ * @return the {@link String}
*/
- public boolean isDirty() {
- return dirty;
- }
+ private void setList(List<String> values, char sep) {
+ StringBuilder builder = new StringBuilder();
+ boolean first = true;
+ for (String value : values) {
+ if (!first)
+ builder.append(sep);
- /**
- * Notify that this element has unsaved changes, and notify its parent of
- * the same if any.
- */
- protected void setDirty() {
- this.dirty = true;
- if (this.parent != null)
- this.parent.setDirty();
- }
+ builder.append(escape(value));
- /**
- * Notify this element <i>and all its descendants</i> that it is in pristine
- * state (as opposed to dirty).
- */
- void setPristine() {
- dirty = false;
- for (TypeInfo type : types) {
- type.setPristine();
+ first = false;
}
+
+ value = builder.toString();
}
- /**
- * Set the parent of this {@link Data}.
- *
- * @param parent
- * the new parent
- */
- void setParent(Contact parent) {
- this.parent = parent;
+ @Override
+ public String getId() {
+ return "" + name;
+ }
+
+ @Override
+ public String getState() {
+ return ("" + name + value + group).replace(' ', '_');
}
}