package com.voxeo.tropo.util; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.UnknownHostException; import java.text.MessageFormat; import java.util.Hashtable; import java.util.Map; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.regex.Pattern; import javax.script.ScriptException; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.sip.ConvergedHttpSession; import javax.servlet.sip.SipApplicationSession; import javax.servlet.sip.SipServletMessage; import javax.servlet.sip.SipServletRequest; import javax.xml.namespace.QName; import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPBodyElement; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPMessage; import javax.xml.ws.BindingProvider; import javax.xml.ws.Dispatch; import javax.xml.ws.Service; import javax.xml.ws.soap.SOAPBinding; import javax.xml.ws.soap.SOAPFaultException; import org.apache.log4j.Logger; import org.apache.log4j.MDC; import com.micromethod.common.util.StringUtils; import com.voxeo.Guido.Guido; import com.voxeo.Guido.GuidoException; import com.voxeo.logging.LoggingContext; import com.voxeo.tropo.Configuration; import com.voxeo.tropo.ServletContextConstants; import com.voxeo.tropo.app.Application; import com.voxeo.tropo.app.ApplicationInstance; public class Utils { private static final Logger LOG = Logger.getLogger(Utils.class); protected static Pattern HttpURLPattern = Pattern.compile("[h|H][t|T][t|T][p|P]://\\S*"); protected static Pattern FileURLPattern = Pattern.compile("[f|F][i|I][l|L][e|E]://\\S*"); protected static Pattern FtpURLPattern = Pattern.compile("[f|F][t|T][p|P]://\\S*"); protected static Pattern DtmfPattern = Pattern.compile("[d|D][t|T][m|M][f|F]:\\S*"); public static final String HOSTNAME; static { String hostname; try { hostname = java.net.InetAddress.getLocalHost().getCanonicalHostName(); } catch (UnknownHostException e) { hostname = "Unknown"; } HOSTNAME = hostname; } public static byte[] genSSML(final String tts, final boolean parse) { String retval = tts; retval = retval.trim(); if (!retval.startsWith("<")) { if (parse) { retval = HttpURLPattern.matcher(retval).replaceAll("<audio src=\"$0\"/>"); retval = FileURLPattern.matcher(retval).replaceAll("<audio src=\"$0\"/>"); retval = FtpURLPattern.matcher(retval).replaceAll("<audio src=\"$0\"/>"); retval = DtmfPattern.matcher(retval).replaceAll("<audio src=\"$0\"/>"); } retval = MessageFormat.format("<?xml version=\"1.0\"?><speak>{0}</speak>", retval); } return retval.getBytes(); } public static String prefixNumber(final String number) { if (number == null || number.length() == 0 || StringUtils.startsWithIgnoreCase(number, "sip:") || StringUtils.startsWithIgnoreCase(number, "tel:") || StringUtils.startsWithIgnoreCase(number, "sip:")) { return number; } if (number.startsWith("+")) { return "tel:" + number; } try { Long.parseLong(number); return "tel:" + number; } catch (final NumberFormatException e) { return "sip:" + number; } } public static String processFrom(final String number, final String ip) { String retval = prefixNumber(number); if (retval == null) { ; } else if (StringUtils.startsWithIgnoreCase(retval, "tel:")) { String local = ip; if (local == null) { local = Configuration.get().getLocalAddress(); } retval = retval.replaceFirst("[t|T][e|E][l|L]:", "sip:") + "@" + local; } return retval; } public static String processTo(final String number) { String retval = prefixNumber(number); final String sbc = Configuration.get().getPhoneSBC(); if (retval == null || sbc == null || sbc.length() == 0 || number.length() == 0) { ; } else if (StringUtils.startsWithIgnoreCase(retval, "sip:") || StringUtils.startsWithIgnoreCase(retval, "sips:")) { if (retval.indexOf("@10.") < 0) { retval = retval.replaceFirst("@", "!") + "@" + sbc; } } else if (StringUtils.startsWithIgnoreCase(retval, "tel:")) { retval = retval.replaceFirst("[t|T][e|E][l|L]:", "sip:") + "@" + sbc; } return retval; } public static String getManifestAttribute(final String jarUrl, final String attribute) throws IOException { final JarFile jar = new JarFile(jarUrl); final Attributes attr = jar.getManifest().getMainAttributes(); final String value = attr.getValue(attribute); jar.close(); return value; } public static void setLogContext(SipServletMessage msg) { ApplicationInstance ai = (ApplicationInstance) msg.getAttribute(ApplicationInstance.INST); if (ai != null) { setLogContext(ai, msg.getCallId()); } } public static void setLogContext(Application app, ServletRequest req) { if (app == null) { return; } String aid = String.valueOf(app.getAccountID()); String pid = null; String sid = null; String cid = "-1"; if (req != null) { SipApplicationSession session = null; if (req instanceof SipServletRequest) { SipServletRequest request = (SipServletRequest) req; session = request.getSession().getApplicationSession(); pid = request.getHeader("x-sid"); cid = request.getCallId(); } else if (req instanceof HttpServletRequest) { session = ((ConvergedHttpSession) ((HttpServletRequest) req).getSession()).getApplicationSession(); } if (session != null && session.isValid()) { sid = (String) session.getAttribute(ServletContextConstants.GUID_SESSION_ID); } } setLogContext(aid, pid, sid, cid); } public static void setLogContext(ApplicationInstance app, String callID) { if (app == null) { return; } String aid = String.valueOf(app.getApp().getAccountID()); String pid = app.getParentSessionId(); String sid = null; SipApplicationSession session = app.getApplicationSession(); if (session.isValid()) { sid = (String) session.getAttribute(ServletContextConstants.GUID_SESSION_ID); } if (callID == null || callID.length() == 0) { callID = "-1"; } setLogContext(aid, pid, sid, callID); } public static void setLogContext(String aid, String pid, String sid, String callID) { final LoggingContext context = LoggingContext.get(); if (context == null) { return; } context.setCommand("1"); context.setAccountID(aid); context.setHost(Utils.HOSTNAME); context.setSessionGUID(pid == null ? "-1" : pid); context.setSessionNumber(sid == null ? "-1" : sid); MDC.put("CallID", callID); } public static String buildScriptExceptionMessage(Object obj, String action, ScriptException e) { String msg = obj.toString() + " has " + action + " errors: " + e.getMessage(); if (e.getLineNumber() > 0) { msg += " at line #" + e.getLineNumber(); if (e.getColumnNumber() > 0) { msg += " and column #" + e.getColumnNumber(); } } if (e.getCause() != null) { msg += " with cause: " + e.getCause(); } return msg; } public static String pythonHome() { String python = System.getProperty("python.home"); if (python == null) { python = System.getenv("python.home"); } if (python == null) { python = System.getenv("JYTHON_HOME"); } if (python != null && new File(python).isDirectory()) { System.setProperty("python.home", python); LOG.info("python.home is " + python); return python; } LOG.error("JYTHON_HOME is NOT defined or the referred directory does not exist!"); return null; } public static String rubyHome() { String jruby = System.getProperty("jruby.home"); if (jruby == null) { jruby = System.getenv("jruby.home"); } if (jruby == null) { jruby = System.getenv("JRUBY_HOME"); } if (jruby != null && new File(jruby).isDirectory()) { System.setProperty("jruby.home", jruby); System.setProperty("com.sun.script.jruby.loadpath", jruby); System.setProperty("com.sun.script.jruby.terminator", "on"); LOG.info("jruby.home is " + jruby); return jruby; } LOG.error("JRUBY_HOME is NOT defined or the referred directory does not exist!"); return null; } public static String getAppDir() { String appDir = System.getProperty("tropo.app.home"); if (appDir == null) { appDir = System.getenv("tropo.app.home"); } if (appDir == null) { appDir = System.getenv("TROPO_APP_HOME"); } if (appDir != null && new File(appDir).isDirectory()) { LOG.info("Tropo app dir is " + appDir); return appDir; } LOG.error("TROPO_APP_HOME is NOT defined or the referred directory does not exist!"); return null; } public static String getGUID() { try { return new Guido(null).toString(); } catch (GuidoException e) { LOG.error("Error generating GUID,", e); return "ERROR"; } } public static String authenticate(String accountServer, String username, String password) throws SOAPFaultException, SOAPException, MalformedURLException { // Qnames for service as defined in wsdl. QName serviceName = new QName("http://localhost/services", "AccountManagementService"); // QName for Port As defined in wsdl. QName portName = new QName("http://localhost/services", "AccountManagement"); // Create a dynamic Service instance Service service = Service.create(new URL(accountServer), serviceName); // Create a dispatch instance Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE); // Use Dispatch as BindingProvider BindingProvider bp = (BindingProvider) dispatch; // Optionally Configure RequestContext to send SOAPAction HTTP Header Map<String, Object> rc = bp.getRequestContext(); rc.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE); rc.put(BindingProvider.SOAPACTION_URI_PROPERTY, "getAccessToken"); // Obtain a preconfigured SAAJ MessageFactory MessageFactory factory = ((SOAPBinding) bp.getBinding()).getMessageFactory(); // Create SOAPMessage Request SOAPMessage request = factory.createMessage(); // Request Header SOAPHeader header = request.getSOAPHeader(); // Request Body SOAPBody body = request.getSOAPBody(); // Compose the soap:Body payload QName payloadName = new QName("http://localhost/services", "getAccessToken", "ns1"); SOAPBodyElement payload = body.addBodyElement(payloadName); SOAPElement message = payload.addChildElement("arg0"); message.addTextNode(username); message = payload.addChildElement("arg1"); message.addTextNode(password); // Invoke the endpoint synchronously SOAPMessage reply = null; reply = dispatch.invoke(request); // process the reply body = reply.getSOAPBody(); QName responseName = new QName("http://localhost/services", "getAccessTokenResponse"); SOAPBodyElement bodyElement = (SOAPBodyElement) body.getChildElements(responseName).next(); String message1 = bodyElement.getTextContent(); return message1; } public static void clearLogContext() { final Hashtable<?, ?> context = MDC.getContext(); if (context != null) { context.clear(); } } }