/* * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. * See terms of license at gnu.org. */ package net.java.sip.communicator.impl.protocol.sip; import gov.nist.javax.sip.stack.*; import java.util.*; import javax.sip.*; import javax.sip.address.*; import javax.sip.header.*; import javax.sip.message.*; import net.java.sip.communicator.util.*; /** * An implementation of the <tt>Router</tt> interface wrapping around JAIN-SIP * RI <tt>DefaultRouter</tt> in order to be able to change the outbound proxy * depending on the account which sent the request. * * @author Sebastien Mazy */ public class ProxyRouter implements Router { /** * Logger for this class. */ private static final Logger logger = Logger.getLogger(ProxyRouter.class); /** * The running JAIN-SIP stack. */ private final SipStack stack; /** * Used to cache the <tt>DefaultRouter</tt>s. One <tt>DefaultRouter</tt> per * outbound proxy. */ private final Map<String, Router> routerCache = new HashMap<String, Router>(); /** * The jain-sip router to use for accounts that do not have a proxy or as a * default. Do not use this attribute directly but getDefaultRouter() (lazy * initialization) */ private Router defaultRouter = null; /** * Simple constructor. Ignores the <tt>defaultRoute</tt> parameter. * * @param stack the currently running stack. * @param defaultRoute ignored parameter. */ public ProxyRouter(SipStack stack, String defaultRoute) { if (stack == null) throw new IllegalArgumentException("stack shouldn't be null!"); this.stack = stack; // we don't care about the provided default route } /** * Returns the next hop for this <tt>Request</tt>. * * @param request <tt>Request</tt> to find the next hop. * @return the next hop for the <tt>request</tt>. */ public Hop getNextHop(Request request) throws SipException { return this.getRouterFor(request).getNextHop(request); } /** * Returns the next hops for this <tt>Request</tt>. * * @param request <tt>Request</tt> to find the next hops. * @return the next hops for the <tt>request</tt>. */ @Deprecated public ListIterator getNextHops(Request request) { return this.getRouterFor(request).getNextHops(request); } /** * Returns the outbound proxy for this <tt>Router</tt>. * * @return the outbound proxy for this <tt>Router</tt>. */ public Hop getOutboundProxy() { // we can't tell our outbound proxy without a request // Emil: we are not quite certain in which cases this method is needed // so we are logging a stack trace here. logger.fatal("If you see this then please please describe your SIP " + "setup and send the following stack trace to" + "dev@sip-communicator.dev.java.net", new Exception()); return null; } /** * Retrieves a DefaultRouter whose default route is the outbound proxy of * the account which sent the <tt>request</tt>, or a default one. * * @param request the <tt>Request</tt> which to retrieve a <tt>Router</tt> * for. * @return a <tt>Router</tt> with the outbound proxy set for this * <tt>request</tt> if needed, or a default router */ private Router getRouterFor(Request request) { // any out-of-dialog or dialog creating request should be marked with // the service which created it Object service = SipApplicationData.getApplicationData(request, SipApplicationData.KEY_SERVICE); if (service instanceof ProtocolProviderServiceSipImpl) { String proxy = ((ProtocolProviderServiceSipImpl) service) .getOutboundProxyString(); // P2P case if (proxy == null) return this.getDefaultRouter(); // outbound proxy case Router router = routerCache.get(proxy); if (router == null) { router = new DefaultRouter(stack, proxy); routerCache.put(proxy, router); } return router; } // check the request is in-dialog ToHeader to = (ToHeader) request.getHeader(ToHeader.NAME); if (to.getTag() == null) logger.error("unable to identify the service which created this " + "out-of-dialog request"); return this.getDefaultRouter(); } /** * Returns and create if needed a default router (no outbound proxy) * * @return a router with no outbound proxy set */ private Router getDefaultRouter() { if (this.defaultRouter == null) this.defaultRouter = new DefaultRouter(stack, null); return this.defaultRouter; } }