/* * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.mobicents.servlet.sip.startup; import javax.naming.Context; import javax.naming.NamingException; import javax.servlet.sip.SipFactory; import javax.servlet.sip.SipSessionsUtil; import javax.servlet.sip.TimerService; import org.apache.catalina.ContainerEvent; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.core.NamingContextListener; import org.apache.log4j.Logger; import org.apache.naming.ContextAccessController; import org.mobicents.servlet.sip.annotations.SipAnnotationProcessor; /** * Helper class used to initialize and populate the JNDI context associated * with each context with the sip factory. * * @author Jean Deruelle * */ public class SipNamingContextListener extends NamingContextListener { private static transient final Logger logger = Logger.getLogger(SipNamingContextListener.class); public static final String NAMING_CONTEXT_SIP_SUBCONTEXT_ADDED_EVENT = "addSipSubcontext"; public static final String NAMING_CONTEXT_SIP_SUBCONTEXT_REMOVED_EVENT = "removeSipSubContext"; public static final String NAMING_CONTEXT_APPNAME_SUBCONTEXT_ADDED_EVENT = "addAppNameSubcontext"; public static final String NAMING_CONTEXT_APPNAME_SUBCONTEXT_REMOVED_EVENT = "removeAppNameSubcontext"; public static final String NAMING_CONTEXT_SIP_FACTORY_ADDED_EVENT = "addSipFactory"; public static final String NAMING_CONTEXT_SIP_FACTORY_REMOVED_EVENT = "removeSipFactory"; public static final String NAMING_CONTEXT_SIP_SESSIONS_UTIL_ADDED_EVENT = "addSipSessionsUtil"; public static final String NAMING_CONTEXT_SIP_SESSIONS_UTIL_REMOVED_EVENT = "removeSipSessionsUtil"; public static final String NAMING_CONTEXT_TIMER_SERVICE_ADDED_EVENT = "addTimerService"; public static final String NAMING_CONTEXT_TIMER_SERVICE_REMOVED_EVENT = "removeTimerService"; public static final String SIP_SUBCONTEXT = "sip"; public static final String SIP_FACTORY_JNDI_NAME = "SipFactory"; public static final String SIP_SESSIONS_UTIL_JNDI_NAME = "SipSessionsUtil"; public static final String TIMER_SERVICE_JNDI_NAME = "TimerService"; @Override public void lifecycleEvent(LifecycleEvent event) { super.lifecycleEvent(event); if (event.getType().equalsIgnoreCase(Lifecycle.START_EVENT)) { if (container instanceof SipContext) { ((SipAnnotationProcessor)((SipContext)container).getAnnotationProcessor()).setContext(envCtx); } } } @Override public void containerEvent(ContainerEvent event) { super.containerEvent(event); // Setting the context in read/write mode ContextAccessController.setWritable(getName(), container); String type = event.getType(); SipContext sipContext = null; String appName = null; if(event.getContainer() instanceof SipContext) { sipContext = (SipContext)event.getContainer(); appName = sipContext.getApplicationName(); } if (type.equals(NAMING_CONTEXT_SIP_SUBCONTEXT_ADDED_EVENT)) { addSipSubcontext(envCtx); if(logger.isDebugEnabled()) { logger.debug("Sip Subcontext added to the JNDI context for container " + event.getContainer()); } } else if (type.equals(NAMING_CONTEXT_SIP_SUBCONTEXT_REMOVED_EVENT)) { removeSipSubcontext(envCtx); if(logger.isDebugEnabled()) { logger.debug("Sip Subcontext removed from the JNDI context for container " + event.getContainer()); } } if (type.equals(NAMING_CONTEXT_APPNAME_SUBCONTEXT_ADDED_EVENT)) { addAppNameSubContext(envCtx, appName); if(logger.isDebugEnabled()) { logger.debug(appName + " Subcontext added to the JNDI context for container " + event.getContainer()); } } else if (type.equals(NAMING_CONTEXT_APPNAME_SUBCONTEXT_REMOVED_EVENT)) { removeAppNameSubContext(envCtx, appName); if(logger.isDebugEnabled()) { logger.debug(appName + " Subcontext removed from the JNDI context for container " + event.getContainer()); } } else if (type.equals(NAMING_CONTEXT_SIP_FACTORY_ADDED_EVENT)) { SipFactory sipFactory = (SipFactory) event.getData(); if (sipFactory != null) { addSipFactory(envCtx, appName, sipFactory); if(logger.isDebugEnabled()) { logger.debug("Sip Factory added to the JNDI context for container " + event.getContainer()); } } } else if (type.equals(NAMING_CONTEXT_SIP_FACTORY_REMOVED_EVENT)) { SipFactory sipFactory = (SipFactory) event.getData(); if (sipFactory != null) { removeSipFactory(envCtx, appName, sipFactory); if(logger.isDebugEnabled()) { logger.debug("Sip Factory removed from the JNDI context for container " + event.getContainer()); } } } else if (type.equals(NAMING_CONTEXT_SIP_SESSIONS_UTIL_ADDED_EVENT)) { SipSessionsUtil sipSessionsUtil = (SipSessionsUtil) event.getData(); if (sipSessionsUtil != null) { addSipSessionsUtil(envCtx, appName, sipSessionsUtil); if(logger.isDebugEnabled()) { logger.debug("SipSessionsUtil added to the JNDI context for container " + event.getContainer()); } } } else if (type.equals(NAMING_CONTEXT_SIP_SESSIONS_UTIL_REMOVED_EVENT)) { SipSessionsUtil sipSessionsUtil = (SipSessionsUtil) event.getData(); if (sipSessionsUtil != null) { removeSipSessionsUtil(envCtx, appName, sipSessionsUtil); if(logger.isDebugEnabled()) { logger.debug("SipSessionsUtil removed from the JNDI context for container " + event.getContainer()); } } } else if (type.equals(NAMING_CONTEXT_TIMER_SERVICE_ADDED_EVENT)) { TimerService timerService = (TimerService) event.getData(); if (timerService != null) { addTimerService(envCtx, appName, timerService); if(logger.isDebugEnabled()) { logger.debug("TimerService added to the JNDI context for container " + event.getContainer()); } } } else if (type.equals(NAMING_CONTEXT_SIP_FACTORY_REMOVED_EVENT)) { TimerService timerService = (TimerService) event.getData(); if (timerService != null) { removeTimerService(envCtx, appName, timerService); if(logger.isDebugEnabled()) { logger.debug("TimerService removed from the JNDI context for container " + event.getContainer()); } } } // Setting the context in read only mode ContextAccessController.setReadOnly(getName()); } /** * Removes the sip subcontext from JNDI * @param envCtx the envContext from which the sip subcontext should be removed */ public static void removeSipSubcontext(Context envCtx) { try { envCtx.destroySubcontext(SIP_SUBCONTEXT); } catch (NamingException e) { logger.error(sm.getString("naming.unbindFailed", e)); } } /** * Add the sip subcontext to JNDI * @param envCtx the envContext to which the sip subcontext should be added */ public static void addSipSubcontext(Context envCtx) { try { envCtx.createSubcontext(SIP_SUBCONTEXT); } catch (NamingException e) { logger.error(sm.getString("naming.bindFailed", e)); } } /** * Removes the app name subcontext from the jndi mapping * @param appName sub context Name */ public static void removeAppNameSubContext(Context envCtx, String appName) { if(envCtx != null) { try { javax.naming.Context sipContext = (javax.naming.Context)envCtx.lookup(SIP_SUBCONTEXT); sipContext.destroySubcontext(appName); } catch (NamingException e) { logger.error(sm.getString("naming.unbindFailed", e)); } } } /** * Add the application name subcontext from the jndi mapping * @param appName sub context Name */ public static void addAppNameSubContext(Context envCtx, String appName) { if(envCtx != null) { try { javax.naming.Context sipContext = (javax.naming.Context)envCtx.lookup(SIP_SUBCONTEXT); sipContext.createSubcontext(appName); } catch (NamingException e) { logger.error(sm.getString("naming.bindFailed", e)); } } } /** * Removes the sip sessions util binding from the jndi mapping * @param appName the application name subcontext * @param sipSessionsUtil the sip sessions util to remove */ public static void removeSipSessionsUtil(Context envCtx, String appName, SipSessionsUtil sipSessionsUtil) { if(envCtx != null) { try { javax.naming.Context sipContext = (javax.naming.Context)envCtx.lookup(SIP_SUBCONTEXT + "/" + appName); sipContext.unbind(SIP_SESSIONS_UTIL_JNDI_NAME); } catch (NamingException e) { logger.error(sm.getString("naming.unbindFailed", e)); } } } /** * Add the sip sessions util binding from the jndi mapping * and bind the sip sessions util in parameter to it * @param appName the application name subcontext * @param sipSessionsUtil the sip sessions util to add */ public static void addSipSessionsUtil(Context envCtx, String appName, SipSessionsUtil sipSessionsUtil) { if(envCtx != null) { try { javax.naming.Context sipContext = (javax.naming.Context)envCtx.lookup(SIP_SUBCONTEXT + "/" + appName); sipContext.bind(SIP_SESSIONS_UTIL_JNDI_NAME, sipSessionsUtil); } catch (NamingException e) { logger.error(sm.getString("naming.bindFailed", e)); } } } /** * Removes the Timer Service binding from the jndi mapping * @param appName the application name subcontext * @param timerService the Timer Service to remove */ public static void removeTimerService(Context envCtx, String appName, TimerService timerService) { if(envCtx != null) { try { javax.naming.Context sipContext = (javax.naming.Context)envCtx.lookup(SIP_SUBCONTEXT + "/" + appName); sipContext.unbind(TIMER_SERVICE_JNDI_NAME); } catch (NamingException e) { logger.error(sm.getString("naming.unbindFailed", e)); } } } /** * Add the sip timer service from the jndi mapping * and bind the timer service in parameter to it * @param appName the application name subcontext * @param timerService the Timer Service to add */ public static void addTimerService(Context envCtx, String appName, TimerService timerService) { if(envCtx != null) { try { javax.naming.Context sipContext = (javax.naming.Context)envCtx.lookup(SIP_SUBCONTEXT + "/" + appName); sipContext.bind(TIMER_SERVICE_JNDI_NAME, timerService); } catch (NamingException e) { logger.error(sm.getString("naming.bindFailed", e)); } } } /** * Removes the sip factory binding from the jndi mapping * @param appName the application name subcontext * @param sipFactory the sip factory to remove */ public static void removeSipFactory(Context envCtx, String appName, SipFactory sipFactory) { if(envCtx != null) { try { javax.naming.Context sipContext = (javax.naming.Context)envCtx.lookup(SIP_SUBCONTEXT + "/" + appName); sipContext.unbind(SIP_FACTORY_JNDI_NAME); } catch (NamingException e) { logger.error(sm.getString("naming.unbindFailed", e)); } } } /** * Add the sip factory binding from the jndi mapping * and bind the sip factory in paramter to it * @param appName * @param sipFactory the sip factory to add */ public static void addSipFactory(Context envCtx, String appName, SipFactory sipFactory) { if(envCtx != null) { try { javax.naming.Context sipContext = (javax.naming.Context)envCtx.lookup(SIP_SUBCONTEXT + "/" + appName); sipContext.bind(SIP_FACTORY_JNDI_NAME, sipFactory); } catch (NamingException e) { logger.error(sm.getString("naming.bindFailed", e)); } } } }