Java tutorial
/* * Copyright (C) 2010 Avaya, certain elements licensed under a Contributor Agreement. * Contributors retain copyright to elements licensed under a Contributor Agreement. * Licensed to the User under the LGPL license. */ package org.sipfoundry.openfire.vcard.provider; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.StringReader; import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import javax.imageio.ImageIO; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamSource; import org.apache.log4j.Logger; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.io.DocumentResult; import org.dom4j.io.DocumentSource; import org.dom4j.io.SAXReader; import org.sipfoundry.commons.userdb.User; import org.sipfoundry.openfire.vcard.provider.SipXVCardProvider; public class RestInterface { public static final String REST_CALL_URL_CONTACT_INFO = System.getProperty("admin.rest.url") + "/sipxconfig/rest/my/contact-information"; public static final int SSL_CONNECTION_TIMEOUT = 10000; // milliseconds public static final int CONNECTION_TIMEOUT = 30000; // milliseconds public static final int READ_TIMEOUT = 30000; // milliseconds private static Logger logger = Logger.getLogger(RestInterface.class); private static RestInterface instance = null; synchronized public static RestInterface getInstance() { if (instance == null) instance = new RestInterface(); return instance; } public static String sendRequest(String method, Element vcardElement) throws ConnectException { try { logger.debug("call REST URL " + REST_CALL_URL_CONTACT_INFO); URL serverURL = new URL(REST_CALL_URL_CONTACT_INFO); HttpURLConnection conn = (HttpURLConnection) serverURL.openConnection(); conn.setReadTimeout(READ_TIMEOUT); conn.setDoOutput(true); conn.setRequestMethod(method); if (vcardElement != null) { conn.setDoInput(true); conn.setRequestProperty("Content-type", "text/xml"); OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); String vcardXml = RestInterface.buildXMLContactInfo(vcardElement); String contactXml = RestInterface.sendRequest(SipXVCardProvider.QUERY_METHOD, null); if (contactXml != null) { vcardXml = refillMissingContactInfo(vcardXml, contactXml); } wr.write(vcardXml); wr.flush(); wr.close(); } conn.connect(); logger.debug( "response code " + conn.getResponseCode() + " response message " + conn.getResponseMessage()); BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuilder resp = new StringBuilder(); String line; while ((line = rd.readLine()) != null) { resp.append(line); } rd.close(); if (conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) { return resp.toString(); } else { logger.error("Response code " + conn.getResponseCode() + ":" + conn.getResponseMessage() + " " + resp.toString()); return null; } } catch (ConnectException ex) { logger.error("In sendRequest ConnectException " + ex.getMessage()); throw ex; } catch (IOException ex) { logger.error("In sendRequest IOException " + ex.getMessage()); return null; } catch (Exception ex) { logger.error("Exception " + ex.getMessage()); return null; } } public String buildXMLContactInfoXSLT(Element e) { try { String x = e.asXML().replace("xmlns=\"vcard-temp\"", ""); // xmlns causes dom4j xpath // not working somehow. Document vcardDoc = DocumentHelper.parseText(x); logger.debug("before XSLT " + vcardDoc.getRootElement().asXML()); InputStream inStream = this.getClass().getResourceAsStream("/contactInfo.xsl"); Document contactDoc = styleDocument(vcardDoc, inStream); logger.debug("After XSLT " + contactDoc.getRootElement().asXML()); return contactDoc.getRootElement().asXML(); } catch (Exception ex) { logger.error(ex.getMessage()); return null; } } public static String buildXMLContactInfo(Element e) { try { String x = e.asXML().replace("xmlns=\"vcard-temp\"", ""); // xmlns causes dom4j xpath // not working somehow. logger.debug("In buildXMLContactInfo vcard string is " + x); Document vcardDoc = DocumentHelper.parseText(x); Element el = vcardDoc.getRootElement(); StringBuilder xbuilder = new StringBuilder("<contact-information>"); xbuilder.append("<firstName>"); xbuilder.append(getNodeText(el, "N/GIVEN")); xbuilder.append("</firstName>"); xbuilder.append("<lastName>"); xbuilder.append(getNodeText(el, "N/FAMILY")); xbuilder.append("</lastName>"); xbuilder.append("<jobTitle>"); xbuilder.append(getNodeText(el, "TITLE")); xbuilder.append("</jobTitle>"); xbuilder.append("<jobDept>"); xbuilder.append(getNodeText(el, "ORG/ORGUNIT")); xbuilder.append("</jobDept>"); xbuilder.append("<companyName>"); xbuilder.append(getNodeText(el, "ORG/ORGNAME")); xbuilder.append("</companyName>"); xbuilder.append("<officeAddress>"); xbuilder.append("<street>"); xbuilder.append(getNodeText(el, "ADR/STREET")); xbuilder.append("</street>"); xbuilder.append("<city>"); xbuilder.append(getNodeText(el, "ADR/LOCALITY")); xbuilder.append("</city>"); xbuilder.append("<country>"); xbuilder.append(getNodeText(el, "ADR/CTRY")); xbuilder.append("</country>"); xbuilder.append("<state>"); xbuilder.append(getNodeText(el, "ADR/REGION")); xbuilder.append("</state>"); xbuilder.append("<zip>"); xbuilder.append(getNodeText(el, "ADR/PCODE")); xbuilder.append("</zip>"); xbuilder.append("</officeAddress>"); /* * if (!(getNodeText(el, "JABBERID").equals("unknown"))) { xbuilder.append("<imId>"); * xbuilder.append(getNodeText(el, "JABBERID"));xbuilder.append("</imId>"); } */ xbuilder.append("<emailAddress>"); xbuilder.append(getNodeText(el, "EMAIL/USERID")); xbuilder.append("</emailAddress>"); xbuilder.append("</contact-information>"); logger.debug("contact info generated by buildXMLContactInfo is " + xbuilder.toString()); return xbuilder.toString(); } catch (Exception ex) { logger.error(ex.getMessage()); return null; } } public Element buildVCardFromXMLContactInfoXSLT(String xmlString) { try { Document contactDoc = DocumentHelper.parseText(xmlString); InputStream inStream = this.getClass().getResourceAsStream("/vCardTemp.xsl"); logger.debug("before XSLT " + contactDoc.getRootElement().asXML()); Document vcardDoc = styleDocument(contactDoc, inStream); logger.debug("After XSLT " + vcardDoc.getRootElement().asXML()); return vcardDoc.getRootElement(); } catch (Exception ex) { logger.error(ex.getMessage()); return null; } } // // Refill the contact information available in sipX but not mentioned in the vcard update // request from XMM client. // Otherwise, those information will be deleted by sipX. // public static String refillMissingContactInfo(String vcardXml, String contactXml) { try { SAXReader sreader = new SAXReader(); Document contactDoc = sreader.read(new StringReader(contactXml)); Element contactRootElement = contactDoc.getRootElement(); Document vcardDoc = sreader.read(new StringReader(vcardXml)); Element vcardRootElement = vcardDoc.getRootElement(); for (Element el : (List<Element>) contactRootElement.elements()) { Element vElement; if ((vElement = vcardRootElement.element(el.getName())) == null) { logger.debug(" In refillMissingContactInfo Element = [" + el.getName() + "] not found!"); vcardRootElement.add(el.createCopy()); } else { String newStr = refillMissingContactInfo(vElement.asXML(), el.asXML()); if ((newStr.compareTo(vElement.asXML()) != 0)) { Document vcardSubDoc = sreader.read(new StringReader(newStr)); Element vcardSubRootElement = vcardSubDoc.getRootElement(); vcardRootElement.remove(vElement); vcardRootElement.add(vcardSubRootElement.createCopy()); } } } logger.debug("vcard XML string after refill is " + vcardRootElement.asXML()); return vcardRootElement.asXML(); } catch (Exception ex) { logger.error(ex.getMessage()); return null; } } public static Element buildVCardFromXMLContactInfo(User user, Element avatarFromDB) { try { SAXReader sreader = new SAXReader(); StringBuilder xbuilder = new StringBuilder("<vCard xmlns='vcard-temp'>"); xbuilder.append("<FN>"); xbuilder.append(defaultContactValue(user.getDisplayName())); xbuilder.append("</FN>"); xbuilder.append("<N>"); xbuilder.append("<FAMILY>"); xbuilder.append(defaultContactValue(user.getLastName())); xbuilder.append("</FAMILY>"); xbuilder.append("<GIVEN>"); xbuilder.append(defaultContactValue(user.getFirstName())); xbuilder.append("</GIVEN>"); xbuilder.append("<MIDDLE/>"); xbuilder.append("</N>"); xbuilder.append("<NICKNAME>"); xbuilder.append(""); xbuilder.append("</NICKNAME>"); xbuilder.append("<URL>"); xbuilder.append(""); xbuilder.append("</URL>"); xbuilder.append("<BDAY>"); xbuilder.append(""); xbuilder.append("</BDAY>"); xbuilder.append("<ORG>"); xbuilder.append("<ORGNAME>"); xbuilder.append(defaultContactValue(user.getCompanyName())); xbuilder.append("</ORGNAME>"); xbuilder.append("<ORGUNIT>"); xbuilder.append(defaultContactValue(user.getJobDepartment())); xbuilder.append("</ORGUNIT>"); xbuilder.append("</ORG>"); xbuilder.append("<TITLE>"); xbuilder.append(defaultContactValue(user.getJobTitle())); xbuilder.append("</TITLE>"); xbuilder.append("<ROLE/>"); xbuilder.append("<TEL>"); xbuilder.append("<WORK/>"); xbuilder.append("<VOICE/>"); xbuilder.append("<NUMBER>"); xbuilder.append(defaultContactValue(user.getUserName())); xbuilder.append("</NUMBER>"); xbuilder.append("</TEL>"); xbuilder.append("<TEL>"); xbuilder.append("<WORK/>"); xbuilder.append("<FAX/>"); xbuilder.append("<NUMBER>"); xbuilder.append(defaultContactValue(user.getFaxNumber())); xbuilder.append("</NUMBER>"); xbuilder.append("</TEL>"); xbuilder.append("<TEL>"); xbuilder.append("<WORK/>"); xbuilder.append("<MSG/>"); xbuilder.append("<NUMBER/>"); xbuilder.append("</TEL>"); xbuilder.append("<ADR>"); xbuilder.append("<WORK/>"); xbuilder.append("<EXTADD>"); xbuilder.append("</EXTADD>"); xbuilder.append("<STREET>"); xbuilder.append(defaultContactValue(user.getOfficeStreet())); xbuilder.append("</STREET>"); xbuilder.append("<LOCALITY>"); xbuilder.append(defaultContactValue(user.getOfficeCity())); xbuilder.append("</LOCALITY>"); xbuilder.append("<REGION>"); xbuilder.append(defaultContactValue(user.getOfficeState())); xbuilder.append("</REGION>"); xbuilder.append("<PCODE>"); xbuilder.append(defaultContactValue(user.getOfficeZip())); xbuilder.append("</PCODE>"); xbuilder.append("<CTRY>"); xbuilder.append(defaultContactValue(user.getOfficeCountry())); xbuilder.append("</CTRY>"); xbuilder.append("</ADR>"); xbuilder.append("<TEL>"); xbuilder.append("<HOME/>"); xbuilder.append("<VOICE/>"); xbuilder.append("<NUMBER>"); xbuilder.append(defaultContactValue(user.getHomeNum())); xbuilder.append("</NUMBER>"); xbuilder.append("</TEL>"); xbuilder.append("<TEL>"); xbuilder.append("<HOME/>"); xbuilder.append("<FAX/>"); xbuilder.append("<NUMBER/>"); xbuilder.append("</TEL>"); xbuilder.append("<TEL>"); xbuilder.append("<CELL/>"); xbuilder.append("<VOICE/>"); xbuilder.append("<NUMBER>"); xbuilder.append(defaultContactValue(user.getCellNum())); xbuilder.append("</NUMBER>"); xbuilder.append("</TEL>"); xbuilder.append("<TEL>"); xbuilder.append("<HOME/>"); xbuilder.append("<MSG/>"); xbuilder.append("<NUMBER/>"); xbuilder.append("</TEL>"); xbuilder.append("<ADR>"); xbuilder.append("<HOME/>"); xbuilder.append("<EXTADD/>"); xbuilder.append("<STREET>"); xbuilder.append(defaultContactValue(user.getHomeStreet())); xbuilder.append("</STREET>"); xbuilder.append("<LOCALITY>"); xbuilder.append(defaultContactValue(user.getHomeCity())); xbuilder.append("</LOCALITY>"); xbuilder.append("<REGION>"); xbuilder.append(defaultContactValue(user.getHomeState())); xbuilder.append("</REGION>"); xbuilder.append("<PCODE>"); xbuilder.append(defaultContactValue(user.getHomeZip())); xbuilder.append("</PCODE>"); xbuilder.append("<CTRY>"); xbuilder.append(defaultContactValue(user.getHomeCountry())); xbuilder.append("</CTRY>"); xbuilder.append("</ADR>"); xbuilder.append("<EMAIL>"); xbuilder.append("<INTERNET/>"); xbuilder.append("<PREF/>"); xbuilder.append("<USERID>"); xbuilder.append(defaultContactValue(user.getEmailAddress())); xbuilder.append("</USERID>"); xbuilder.append("</EMAIL>"); xbuilder.append("<JABBERID>"); xbuilder.append(defaultContactValue(user.getJid())); xbuilder.append("</JABBERID>"); xbuilder.append("<DESC/>"); if (avatarFromDB == null) { String encodedStr = getEncodedAvatar(defaultContactValue(user.getAvatar())); if (encodedStr != null) { xbuilder.append("<PHOTO>"); xbuilder.append("<TYPE>image/png</TYPE>"); xbuilder.append("<BINVAL>"); xbuilder.append(encodedStr); xbuilder.append("</BINVAL>"); xbuilder.append("</PHOTO>"); } } xbuilder.append("</vCard>"); // The following are Not supported by XMPP vcard temp XEP-0054 so far. /* * <contact-information> <assistantName>adfafd</assistantName> * <location>afaf</location> <assistantPhoneNumber>afdadf</assistantPhoneNumber> * <imDisplayName>201_IM_test</imDisplayName> <alternateImId>afa</alternateImId> * <alternateEmailAddress>afafd</alternateEmailAddress> * </contact-information>-bash-3.2$ */ logger.debug("vcard generated by buildVCardFromXMLContactinfo is " + xbuilder.toString()); Document vcardDoc = sreader.read(new StringReader(xbuilder.toString())); Element vcardNode = vcardDoc.getRootElement(); if (avatarFromDB != null) { vcardNode.add(avatarFromDB); } return vcardNode; } catch (Exception ex) { logger.error(ex.getMessage()); return null; } } private static String defaultContactValue(String value) { return StringUtils.defaultString(value, StringUtils.EMPTY); } public static String getNodeText(Element element, String nodeName) { Node node = element.selectSingleNode(nodeName); if (node != null) { return node.getText(); } return ""; } public static String getTextFromNodes(Element element, String nameNode, String criteriaNode, String valueNode) { List nlist = element.selectNodes(nameNode); for (int i = 0; i < nlist.size(); i++) { Element el = (Element) (nlist.get(i)); Node cNode = el.selectSingleNode(criteriaNode); if (cNode != null) { Node vNode = el.selectSingleNode(valueNode); if (vNode != null) { return vNode.getText(); } } } return ""; } public static Document styleDocument(Document document, InputStream stylesheet) throws Exception { // load the transformer using JAXP TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(new StreamSource(stylesheet)); // now lets style the given document DocumentSource source = new DocumentSource(document); DocumentResult result = new DocumentResult(); transformer.transform(source, result); // return the transformed document Document transformedDoc = result.getDocument(); return transformedDoc; } public static String getEncodedAvatar(String avatarURL) { logger.debug("Avatar URL " + avatarURL); return getPngStringTimeout(avatarURL); } public static String getPngString(URL url) { try { ByteArrayOutputStream os = new ByteArrayOutputStream(); BufferedImage image = ImageIO.read(url); ImageIO.write(image, "png", os); return new String(new Base64().encode(os.toByteArray())); } catch (IOException e) { logger.error("In getPngString, error:" + e.getMessage()); return null; } catch (Exception e) { logger.error(e.getMessage()); return null; } } public static String getPngStringTimeout(String urlStr) { try { URL url = new URL(urlStr); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); if (url.getProtocol().equalsIgnoreCase("https")) { TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { } } }; SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); ((HttpsURLConnection) conn).setSSLSocketFactory(sc.getSocketFactory()); } conn.setConnectTimeout(CONNECTION_TIMEOUT); conn.setReadTimeout(READ_TIMEOUT); conn.setRequestMethod("GET"); conn.connect(); ByteArrayOutputStream os = new ByteArrayOutputStream(); BufferedImage image = ImageIO.read(conn.getInputStream()); ImageIO.write(image, "png", os); return new String(new Base64().encode(os.toByteArray())); } catch (MalformedURLException e) { logger.error("In getPngStringTimeout, MalformedURLException:" + e.getMessage()); return null; } catch (IOException e) { logger.error("In getPngStringTimeout, IOException:" + e.getMessage()); return null; } catch (Exception e) { logger.error("In getPngStringTimeout, Exception:" + e.getMessage()); return null; } } }