aboutsummaryrefslogtreecommitdiff
path: root/src/org/jivesoftware/smackx/provider/VCardProvider.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/jivesoftware/smackx/provider/VCardProvider.java')
-rw-r--r--src/org/jivesoftware/smackx/provider/VCardProvider.java293
1 files changed, 293 insertions, 0 deletions
diff --git a/src/org/jivesoftware/smackx/provider/VCardProvider.java b/src/org/jivesoftware/smackx/provider/VCardProvider.java
new file mode 100644
index 0000000..8fa0421
--- /dev/null
+++ b/src/org/jivesoftware/smackx/provider/VCardProvider.java
@@ -0,0 +1,293 @@
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx.provider;
+
+import org.jivesoftware.smack.packet.IQ;
+import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smackx.packet.VCard;
+import org.w3c.dom.*;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * vCard provider.
+ *
+ * @author Gaston Dombiak
+ * @author Derek DeMoro
+ */
+public class VCardProvider implements IQProvider {
+
+ private static final String PREFERRED_ENCODING = "UTF-8";
+
+ public IQ parseIQ(XmlPullParser parser) throws Exception {
+ final StringBuilder sb = new StringBuilder();
+ try {
+ int event = parser.getEventType();
+ // get the content
+ while (true) {
+ switch (event) {
+ case XmlPullParser.TEXT:
+ // We must re-escape the xml so that the DOM won't throw an exception
+ sb.append(StringUtils.escapeForXML(parser.getText()));
+ break;
+ case XmlPullParser.START_TAG:
+ sb.append('<').append(parser.getName()).append('>');
+ break;
+ case XmlPullParser.END_TAG:
+ sb.append("</").append(parser.getName()).append('>');
+ break;
+ default:
+ }
+
+ if (event == XmlPullParser.END_TAG && "vCard".equals(parser.getName())) break;
+
+ event = parser.next();
+ }
+ }
+ catch (XmlPullParserException e) {
+ e.printStackTrace();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ String xmlText = sb.toString();
+ return createVCardFromXML(xmlText);
+ }
+
+ /**
+ * Builds a users vCard from xml file.
+ *
+ * @param xml the xml representing a users vCard.
+ * @return the VCard.
+ * @throws Exception if an exception occurs.
+ */
+ public static VCard createVCardFromXML(String xml) throws Exception {
+ VCard vCard = new VCard();
+
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ Document document = documentBuilder.parse(
+ new ByteArrayInputStream(xml.getBytes(PREFERRED_ENCODING)));
+
+ new VCardReader(vCard, document).initializeFields();
+ return vCard;
+ }
+
+ private static class VCardReader {
+
+ private final VCard vCard;
+ private final Document document;
+
+ VCardReader(VCard vCard, Document document) {
+ this.vCard = vCard;
+ this.document = document;
+ }
+
+ public void initializeFields() {
+ vCard.setFirstName(getTagContents("GIVEN"));
+ vCard.setLastName(getTagContents("FAMILY"));
+ vCard.setMiddleName(getTagContents("MIDDLE"));
+ setupPhoto();
+
+ setupEmails();
+
+ vCard.setOrganization(getTagContents("ORGNAME"));
+ vCard.setOrganizationUnit(getTagContents("ORGUNIT"));
+
+ setupSimpleFields();
+
+ setupPhones();
+ setupAddresses();
+ }
+
+ private void setupPhoto() {
+ String binval = null;
+ String mimetype = null;
+
+ NodeList photo = document.getElementsByTagName("PHOTO");
+ if (photo.getLength() != 1)
+ return;
+
+ Node photoNode = photo.item(0);
+ NodeList childNodes = photoNode.getChildNodes();
+
+ int childNodeCount = childNodes.getLength();
+ List<Node> nodes = new ArrayList<Node>(childNodeCount);
+ for (int i = 0; i < childNodeCount; i++)
+ nodes.add(childNodes.item(i));
+
+ String name = null;
+ String value = null;
+ for (Node n : nodes) {
+ name = n.getNodeName();
+ value = n.getTextContent();
+ if (name.equals("BINVAL")) {
+ binval = value;
+ }
+ else if (name.equals("TYPE")) {
+ mimetype = value;
+ }
+ }
+
+ if (binval == null || mimetype == null)
+ return;
+
+ vCard.setAvatar(binval, mimetype);
+ }
+
+ private void setupEmails() {
+ NodeList nodes = document.getElementsByTagName("USERID");
+ if (nodes == null) return;
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Element element = (Element) nodes.item(i);
+ if ("WORK".equals(element.getParentNode().getFirstChild().getNodeName())) {
+ vCard.setEmailWork(getTextContent(element));
+ }
+ else {
+ vCard.setEmailHome(getTextContent(element));
+ }
+ }
+ }
+
+ private void setupPhones() {
+ NodeList allPhones = document.getElementsByTagName("TEL");
+ if (allPhones == null) return;
+ for (int i = 0; i < allPhones.getLength(); i++) {
+ NodeList nodes = allPhones.item(i).getChildNodes();
+ String type = null;
+ String code = null;
+ String value = null;
+ for (int j = 0; j < nodes.getLength(); j++) {
+ Node node = nodes.item(j);
+ if (node.getNodeType() != Node.ELEMENT_NODE) continue;
+ String nodeName = node.getNodeName();
+ if ("NUMBER".equals(nodeName)) {
+ value = getTextContent(node);
+ }
+ else if (isWorkHome(nodeName)) {
+ type = nodeName;
+ }
+ else {
+ code = nodeName;
+ }
+ }
+ if (code == null || value == null) continue;
+ if ("HOME".equals(type)) {
+ vCard.setPhoneHome(code, value);
+ }
+ else { // By default, setup work phone
+ vCard.setPhoneWork(code, value);
+ }
+ }
+ }
+
+ private boolean isWorkHome(String nodeName) {
+ return "HOME".equals(nodeName) || "WORK".equals(nodeName);
+ }
+
+ private void setupAddresses() {
+ NodeList allAddresses = document.getElementsByTagName("ADR");
+ if (allAddresses == null) return;
+ for (int i = 0; i < allAddresses.getLength(); i++) {
+ Element addressNode = (Element) allAddresses.item(i);
+
+ String type = null;
+ List<String> code = new ArrayList<String>();
+ List<String> value = new ArrayList<String>();
+ NodeList childNodes = addressNode.getChildNodes();
+ for (int j = 0; j < childNodes.getLength(); j++) {
+ Node node = childNodes.item(j);
+ if (node.getNodeType() != Node.ELEMENT_NODE) continue;
+ String nodeName = node.getNodeName();
+ if (isWorkHome(nodeName)) {
+ type = nodeName;
+ }
+ else {
+ code.add(nodeName);
+ value.add(getTextContent(node));
+ }
+ }
+ for (int j = 0; j < value.size(); j++) {
+ if ("HOME".equals(type)) {
+ vCard.setAddressFieldHome((String) code.get(j), (String) value.get(j));
+ }
+ else { // By default, setup work address
+ vCard.setAddressFieldWork((String) code.get(j), (String) value.get(j));
+ }
+ }
+ }
+ }
+
+ private String getTagContents(String tag) {
+ NodeList nodes = document.getElementsByTagName(tag);
+ if (nodes != null && nodes.getLength() == 1) {
+ return getTextContent(nodes.item(0));
+ }
+ return null;
+ }
+
+ private void setupSimpleFields() {
+ NodeList childNodes = document.getDocumentElement().getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ Node node = childNodes.item(i);
+ if (node instanceof Element) {
+ Element element = (Element) node;
+
+ String field = element.getNodeName();
+ if (element.getChildNodes().getLength() == 0) {
+ vCard.setField(field, "");
+ }
+ else if (element.getChildNodes().getLength() == 1 &&
+ element.getChildNodes().item(0) instanceof Text) {
+ vCard.setField(field, getTextContent(element));
+ }
+ }
+ }
+ }
+
+ private String getTextContent(Node node) {
+ StringBuilder result = new StringBuilder();
+ appendText(result, node);
+ return result.toString();
+ }
+
+ private void appendText(StringBuilder result, Node node) {
+ NodeList childNodes = node.getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ Node nd = childNodes.item(i);
+ String nodeValue = nd.getNodeValue();
+ if (nodeValue != null) {
+ result.append(nodeValue);
+ }
+ appendText(result, nd);
+ }
+ }
+ }
+}