}
}
+ /**
+ * Escape the given value to VCF standard.
+ *
+ * @param value
+ * the value to escape
+ *
+ * @return the escaped value
+ */
+ protected String escape(String value) {
+ if (value == null)
+ return null;
+
+ return value.replaceAll(",", "\\\\,").replaceAll(";", "\\\\;")
+ .replaceAll("\n", "\\\\n");
+ }
+
+ /**
+ * Escape the given value to VCF standard.
+ *
+ * @param value
+ * the value to escape
+ *
+ * @return the escaped value
+ */
+ protected String unescape(String value) {
+ if (value == null)
+ return null;
+
+ return value.replaceAll("\\\\,", ",").replaceAll("\\\\;", ";")
+
+ .replaceAll("\\\\n", "\n");
+ }
+
/**
* Each element that leaves the parent will pass trough here.
*
package be.nikiroo.jvcard;
import java.security.InvalidParameterException;
+import java.util.LinkedList;
import java.util.List;
/**
* @return the value
*/
public String getValue() {
+ return unescape(value);
+ }
+
+ /**
+ * Return the RAW value of this {@link Data}
+ *
+ * @return the RAW value
+ */
+ public String getRawValue() {
return value;
}
* the new value
*/
public void setValue(String value) {
+ value = escape(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 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));
+ }
+ }
+
+ rep.add(value.substring(last));
+ }
+
+ return rep;
}
/**
- * Check if this {@link Data} has the "preferred" flag.
+ * 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 isPreferred() {
- for (TypeInfo type : this) {
- if (type.getName().equals("TYPE") && type.getValue().equals("pref")) {
- return true;
- }
+ private void setList(List<String> values, char sep) {
+ StringBuilder builder = new StringBuilder();
+ boolean first = true;
+ for (String value : values) {
+ if (!first)
+ builder.append(sep);
+
+ builder.append(escape(value));
+
+ first = false;
}
- return false;
+ value = builder.toString();
}
@Override
* @author niki
*
*/
-@SuppressWarnings("rawtypes")
public class TypeInfo extends BaseClass<TypeInfo> {
private String name;
private String value;
* @param value
* its value (<b>MUST NOT</b> be NULL)
*/
- @SuppressWarnings("unchecked")
public TypeInfo(String name, String value) {
super(null);
this.name = name.toUpperCase();
- this.value = value.toString(); // crash NOW if null
+ this.value = escape(value.toString()); // crash NOW if null
}
/**
* @return the value
*/
public String getValue() {
+ return unescape(value);
+ }
+
+ /**
+ * Return the RAW value
+ *
+ * @return the RAW value
+ */
+ public String getRawValue() {
return value;
}
dataBuilder.append(type.getName());
if (type.getValue() != null && !type.getValue().trim().equals("")) {
dataBuilder.append('=');
- dataBuilder.append(type.getValue());
+ dataBuilder.append(type.getRawValue());
}
}
dataBuilder.append(':');
// TODO: bkey!
- dataBuilder.append(data.getValue());
+ dataBuilder.append(data.getRawValue());
// RFC says: Content lines SHOULD be folded to a maximum width of 75
// octets -> since it is SHOULD, we will just cut it as 74/75 chars
if (all) {
for (Data data : contact.getData(field)) {
if (data.isPreferred()) {
- infoPanel
- .addComponent(el.createLabel(StringUtils
- .padString(label, labelSize)
- + contact
- .getPreferredDataValue(field)));
+ infoPanel.addComponent(el
+ .createLabel(StringUtils.padString(
+ label, labelSize)
+ + data.toString()));
} else {
infoPanel
- .addComponent(UiColors.Element.VIEW_CONTACT_NORMAL.createLabel(StringUtils
- .padString(label, labelSize)
- + contact
- .getPreferredDataValue(field)));
+ .addComponent(UiColors.Element.VIEW_CONTACT_NORMAL
+ .createLabel(StringUtils
+ .padString(label,
+ labelSize)
+ + data.toString()));
}
}
} else {
+ String val = contact.getPreferredDataValue(field);
+ if (val == null)
+ val = "";
infoPanel.addComponent(el.createLabel(StringUtils
- .padString(label, labelSize)
- + contact.getPreferredDataValue(field)));
+ .padString(label, labelSize) + val));
}
} else {
String label = info;
String notes = contact.getPreferredDataValue("NOTE");
if (notes == null)
notes = "";
- note.setText(notes.replaceAll("\\\\n", "\n"));
+ note.setText(notes);
Data photo = contact.getPreferredData("PHOTO");
if (photo != null) {
} else {
// TODO: configure size?
int w = getSize().getColumns() - 40;
- int h = getSize().getRows() - 5;
+ int h = getSize().getRows() - 9;
if (w <= 0 || h <= 0)
return null;
public String getDefaultAnswer() {
Data data = getData();
if (data != null) {
- return data.getValue();
+ return data.getValue().replaceAll("\n", "\\\\n");
}
return null;
public String callback(String answer) {
Data data = getData();
if (data != null) {
- data.setValue(answer);
+ data.setValue(answer.replaceAll("\\\\n", "\n"));
return null;
}
StringBuilder valueBuilder = new StringBuilder(" ");
if (!extMode) {
- valueBuilder.append(data.getValue());
+ valueBuilder.append(data.getValue().replaceAll("\n", "\\\\n"));
if (data.getGroup() != null && data.getGroup().length() > 0) {
valueBuilder.append("(");
valueBuilder.append(data.getGroup());
if (builder == null)
builder = new StringBuilder();
- for (int indexType = 0; indexType < data.size(); indexType++) {
- TypeInfo type = data.get(indexType);
+ for (TypeInfo type : data) {
if (builder.length() > 1)
builder.append(", ");
builder.append(type.getName().replaceAll(",", "\\,"));