/**
*
*/
package org.ariadne_eu.utils;
import java.io.IOException;
import java.io.StringReader;
import java.util.Iterator;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import net.sf.vcard4j.java.type.FN;
import net.sf.vcard4j.java.type.VERSION;
import net.sf.vcard4j.parser.DomParser;
import net.sf.vcard4j.parser.VCardException;
import org.w3c.dom.Document;
/**
* @author gonzalo
*
*/
public class VCardUtils {
protected DocumentBuilder documentBuilder = null;
protected static final int[] VCARD_VERSION = {3,0};
protected DomParser vCardParser = new DomParser();
public VCardUtils() {
init();
}
private void init() {
try {
documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void parseVcard(String vcardString, boolean unescape) {
if (unescape)
vcardString = unescapeEntity(vcardString);
vCardParser.setConvertVersion(false);
Document vCardDocument;
vCardDocument = documentBuilder.newDocument();
try {
vCardParser.parse(new StringReader(vcardString), vCardDocument);
} catch (IOException ioe) {
VCardException pe = new VCardException(ioe.getClass().getName() + ": " + ioe.getMessage());
pe.initCause(ioe);
throw pe;
}
org.w3c.dom.Element addressBookElement = vCardDocument.getDocumentElement();
org.w3c.dom.Element vCardElement = (org.w3c.dom.Element) addressBookElement.getElementsByTagNameNS(DomParser.VCARD4J_NAMESPACE, DomParser.XML_VCARD).item(0);
net.sf.vcard4j.java.VCard vCard = new net.sf.vcard4j.java.VCard(vCardElement);
Iterator nIterator = vCard.getTypes("FN");
FN fn = (nIterator.hasNext()) ? (FN) nIterator.next() : null;
if (fn == null) {
System.out.println("vCard has null FN type");
} else {
System.out.println((String) fn.getValue());
}
Iterator versionIterator = vCard.getTypes("VERSION");
VERSION version = (versionIterator.hasNext()) ? (VERSION) versionIterator.next() : null;
if ((version == null) || (version.get() == null))
System.out.println("vCard has null VERSION type");
int[] versionNum;
try {
versionNum = getVersion(version.get());
if (compareVersions(versionNum, VCARD_VERSION) < 0) {
String ver = version.get();
if (ver == null || ver.equals(""))
ver = "empty";
System.out.println("Invalid vCard VERSION (version given was " + ver + ", must be " + parseVersion(VCARD_VERSION) + " or higher)");
}
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
}
public String getFN(String vcardString, boolean unescape) {
if (unescape)
vcardString = unescapeEntity(vcardString);
vCardParser.setConvertVersion(false);
Document vCardDocument;
vCardDocument = documentBuilder.newDocument();
try {
vCardParser.parse(new StringReader(vcardString), vCardDocument);
} catch (IOException ioe) {
VCardException pe = new VCardException(ioe.getClass().getName() + ": " + ioe.getMessage());
pe.initCause(ioe);
throw pe;
}
org.w3c.dom.Element addressBookElement = vCardDocument.getDocumentElement();
org.w3c.dom.Element vCardElement = (org.w3c.dom.Element) addressBookElement.getElementsByTagNameNS(DomParser.VCARD4J_NAMESPACE, DomParser.XML_VCARD).item(0);
net.sf.vcard4j.java.VCard vCard = new net.sf.vcard4j.java.VCard(vCardElement);
Iterator nIterator = vCard.getTypes("FN");
FN fn = (nIterator.hasNext()) ? (FN) nIterator.next() : null;
if (fn == null) {
System.out.println("vCard has null FN type");
return null;
} else {
return ((String) fn.getValue());
}
}
/**
* Extract a hierarchical version number (1.2.1) from a String.
*/
protected int[] getVersion(String versionString) throws NumberFormatException {
if (versionString == null || versionString.equals("")) return new int[] {0};
String[] versionComps = versionString.split("\\.");
int[] versionNums = new int[versionComps.length];
for (int i = 0; i < versionComps.length; i++)
versionNums[i] = Integer.parseInt(versionComps[i]);
return versionNums;
}
/**
* Extract a hierarchical version number (1.2.1) from a String.
*/
protected String parseVersion( int[] version){
if (version == null || version.length == 0) return "0";
String versionString = Integer.toString(version[0]);
for (int i = 1; i < version.length; i++)
versionString += "." + Integer.toString(version[i]);
return versionString;
}
/**
* Compare two hierarchical numeric version numbers (ie 1.0 vs 1.2.1).
*/
protected int compareVersions(int[] version1, int[] version2) {
int max = Math.max(version1.length, version2.length);
for (int i = 0; i < max; i++) {
int v1 = (i < version1.length) ? version1[i] : 0;
int v2 = (i < version2.length) ? version2[i] : 0;
if (v1 < v2) return -1;
if (v1 > v2) return 1;
}
return 0;
}
public String unescapeEntity(String entity) {
entity = mkNull(entity, true);
if (entity == null) return null;
entity = entity.replaceAll("\r\n[ \t]", ""); // RFC2425 sec 5.8.1 MIME-DIR unfolding: remove any CRLF followed by a space or tab
entity = entity.replaceAll("\\\\[nN]", "\r\n"); // RFC2426 sec 2.4.2 'vcard value type' decoding: replace "\n" or "\N" strings with a real CRLF
entity = entity.replaceAll("\\\\,", ","); // replace "\," strings with a real comma
entity = entity.replaceAll("\\\\;", ";");
entity = entity.replaceAll("\\\\:", ":");
entity = entity.replaceAll("\\\\\\\\", "\\");
return entity;
}
protected String mkNull(String s, boolean trim) {
if (s == null) return null;
if (trim) s = s.trim();
if (s.length() == 0) return null;
return s;
}
public static void main(String[] args) {
String vcard = "BEGIN:VCARD\nFN:alba fuertes\nN:fuertes;alba;;;\nNICKNAME:alba\nVERSION:3.0\nEND:VCARD";
VCardUtils u = new VCardUtils();
u.parseVcard(vcard, false);
}
}