--- /dev/null
+package de.j32.jpim.conduit;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import de.j32.jpim.data.Entry;
+import de.j32.jpim.data.EntryConsumer;
+import de.j32.util.XmlUtil;
+
+public class FritzAddressbookImporter implements Importer
+{
+ Document xml_;
+
+ /**
+ * Importer reading Addressbook from Fritzbox XML file
+ *
+ * @param is InputStream providing the XML data. <em>After successful</em>
+ * construction, the class takes responsibility for closing the
+ * stream.
+ * @throws SAXException
+ * @throws IOException
+ */
+ public FritzAddressbookImporter(InputStream is) throws SAXException, IOException
+ {
+ // It does not make sens to try / finally here, at least conceptually:
+ // Since the base-class constructor might throw we would never get a
+ // chance to // properly close is. Thus I deem it safer to only take
+ // responsibility for is when the constructor does NOT throw and place
+ // the try finally into the callers code.
+ xml_ = XmlUtil.parse(is);
+ is.close();
+ }
+
+ @Override
+ public void sendTo(EntryConsumer consumer)
+ {
+ for (Element node : XmlUtil.iterate(xml_.getElementsByTagName("contact"), Element.class)) {
+
+ // subnodes: category (unused, always 0) person/realName
+ // person/imageURL telephony/number (@prio, @type, @vanity)
+ // services/email mod_time
+ Entry entry = new Entry();
+
+ try {
+ entry.name(node.getElementsByTagName("realName").item(0).getTextContent());
+
+ for (Element phone : XmlUtil.iterate(node.getElementsByTagName("number"),
+ Element.class)) {
+ entry.attribute("phone", phone.getAttribute("type"), phone.getTextContent());
+ }
+
+ try {
+ entry.attribute("email", "", node.getElementsByTagName("email").item(0)
+ .getTextContent());
+ }
+ catch (NullPointerException e) {} // ignore missing optional
+ // email
+ }
+ catch (NullPointerException e) {
+ // Ignore incomplete entries
+ entry = null;
+ }
+
+ if (entry != null) consumer.consume(entry);
+ }
+ }
+
+ @Override
+ public void close() throws IOException
+ {}
+
+}