Cardme is a Java VCard library whose goals are to provide an easy to use yet very flexible way of building VCards. Cardme (as of v0.2.0) supports V3.0 VCard format where as older versions support V2.1.

Cardme uses an object oriented approact to reading, writing and building VCards. Every feature of a VCard is modular and so are their types and parameters. We give you the flexibility of controlling the formatting of the textual output. We provide special classes that control the formatting of parameter types and ISO codes. There is a compatibility framework in use which allows for reading and writing of vcard features to be modified to suit the target application's standards.

A strict emphasis on documentation and code style has been put into effect to allow the project source to remain readable and maintainable. Any source code that is mixed with many formatting styles will cause many headaches for contributers and developers.

Error handling interfaces and implementation have been added to allow exceptions to be thrown once detected or caught and stored within a VCard object and then accessed later for repair or reporting.

Persistence interfaces have been added to make persisting vcards in a database easier. One can write the VCard completely as a CLOB in a database table and then read it and parse it back into a Java object. But what if we want to use the RFC-2426 implementation of a contact as a model to structure contact database and make it completely compatible with exporting it as a VCard? this is where the persistence interface comes into play. It allows each feature to be marked for persistence and each can be marked as INSERT,UPDATE,DELETE or UNMARKED so that they can be diverted to the appropriate SQL code.

Cardme now is in its V3.0 testing phase and all errors should be reported as bugs and will be fixed as soon as possible.


Visit Cardme's main download page: Files
Download Cardme JAR library: Jar Files.
Download Cardme Source package: Source Files.
Download Cardme Javadoc: Javadoc.


Get help and support at our forums: Visit Forum.
Post bugs and help make Cardme better: Report a Bug.

Cardme is easy to use as doing the following:

  • 1. Get a list of File objects that represent the VCards (.VCF files) to be parsed.
  • 2. Send them to the VCardEngine's parse() method
  • 3. A VCard object is returned from the parse() method

After this you can check the VCardEngine or each VCard if errors were detected. Each error can be retrieved and has a severity, message and stack trace available.

Writng a VCard object to a .VCF file can be acheived by doing the following:

  • 1. Create an instance of VCardWriter
  • 2. Set various compatibility and formatting modes
  • 3. Set a VCard to the write with .setVCard() method
  • 4. Write the vcard using the .buildVCardString() method
  • 5. Do whatever you want with the resulting string

You can ask the VCardWriter if it had any error using .hasErrors() method

Below is the complete source code of TestParse.java to show how to do it all.

import info.ineighborhood.cardme.io.CompatibilityMode;
import info.ineighborhood.cardme.io.VCardWriter;
import info.ineighborhood.cardme.util.StringUtil;
import info.ineighborhood.cardme.vcard.VCard;
import info.ineighborhood.cardme.vcard.VCardImpl;
import info.ineighborhood.cardme.vcard.errors.VCardError;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

/**
 * Copyright (c) 2004, Neighborhood Technologies
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * 
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * 
 * Neither the name of Neighborhood Technologies nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * 
 * @author George El-Haddad
 * 
 * Mar 10, 2010
 * 
 * A Test class to see how to use the VCardEngine.
 * 
 */
public class TestParser {

	private File[] vcardFiles = null;
	private VCardEngine vcardEngine = null;
	
	/**
	 * Creates a new TestParser.
	 */
	public TestParser() {
		vcardEngine = new VCardEngine();
	}
	
	/**
	 * Sets the compatibility mode.
	 *
	 * @param compatMode
	 */
	public void setCompatibilityMode(CompatibilityMode compatMode) {
		vcardEngine.setCompatibilityMode(compatMode);
	}
	
	/**
	 * Retrieve all VCard files and then parse them.
	 *
	 * @return {@link List}<VCard>
	 */
	public List importVCards() {
		List vcards = new ArrayList();
		vcardFiles = getFiles();
		for(int i = 0; i < vcardFiles.length; i++) {
			try {
				VCard vcard = vcardEngine.parse(vcardFiles[i]);
				vcards.add(vcard);
			}
			catch(IOException ioe) {
				System.err.println("Could not read vcard file: "+vcardFiles[i].getAbsolutePath());
				ioe.printStackTrace();
			}
		}
		
		return vcards;
	}

	/**
	 * Opens a file chooser dialog to select VCard files.
	 * 
	 * @return {@link File}[]
	 */
	private File[] getFiles()
	{
		JFileChooser chooser = new JFileChooser();
		chooser.setDialogTitle("Select VCards");
		chooser.setCurrentDirectory(new File(System.getProperties().getProperty("user.home")));
		chooser.setMultiSelectionEnabled(true);
		chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
			@Override
			public boolean accept(File f) {
				return f.getName().toLowerCase().endsWith(".vcf") || f.isDirectory();
			}

			public @Override
			String getDescription() {

				return "VCard Files";
			}
		});

		int result = chooser.showOpenDialog(null);
		if(result == JFileChooser.CANCEL_OPTION) {
			return null;
		}

		try {
			File[] files = chooser.getSelectedFiles(); // get the file
			return files;
		}
		catch(Exception ex) {
			JOptionPane.showMessageDialog(null, "Warning! Could not load the file(s)!", "Warning!", JOptionPane.WARNING_MESSAGE);
			return null;
		}
	}

	/**
	 * This is the main method. Here the TestParses in created and initialized.
	 * A VCardWriter is created to write the imported vcards to the System.out so
	 * we can see if everything got imported and written correctly.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {

		TestParser testParser = new TestParser();
		testParser.setCompatibilityMode(CompatibilityMode.RFC2426);
		List vcards = testParser.importVCards();
		VCardWriter writer = new VCardWriter();
		
		for(int i = 0; i < vcards.size(); i++) {
			VCardImpl vcard = (VCardImpl)vcards.get(i);
			writer.setVCard(vcard);
			String vstring = writer.buildVCardString();
			
			if(writer.hasErrors()) {
				List errors = vcard.getErrors();
				for(int j = 0; j < errors.size(); j++) {
					System.out.println(StringUtil.formatException(errors.get(j).getError()));
				}
			}
			
			System.out.println(vstring);
		}
		
		System.out.println("\n-- END --");
	}
}