/* * 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.jboss; import javax.management.ObjectName; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NameNotFoundException; import javax.naming.OperationNotSupportedException; import javax.servlet.sip.SipFactory; import javax.servlet.sip.SipSessionsUtil; import javax.servlet.sip.TimerService; import org.jboss.deployment.DeploymentInfo; import org.jboss.metadata.WebMetaData; import org.jboss.util.naming.NonSerializableFactory; import org.jboss.util.naming.Util; import org.jboss.web.AbstractWebContainer; import org.jboss.web.WebApplication; import org.jboss.web.tomcat.service.DeployerConfig; import org.jboss.web.tomcat.service.TomcatDeployer; import org.mobicents.servlet.sip.startup.SipHostConfig; import org.mobicents.servlet.sip.startup.SipNamingContextListener; /** * @author jean.deruelle * */ public class TomcatConvergedDeployer extends TomcatDeployer { private DeployerConfig config; protected String applicationName; protected SipFactory sipFactoryFacade; protected TimerService timerService; protected SipSessionsUtil sipSessionsUtil; @Override public void init(Object containerConfig) throws Exception { super.init(containerConfig); this.config = (DeployerConfig) containerConfig; } @Override protected void performDeployInternal(String hostName, WebApplication appInfo, String warUrl, AbstractWebContainer.WebDescriptorParser webAppParser) throws Exception { super.performDeployInternal(hostName, appInfo, warUrl, webAppParser); if(log.isDebugEnabled()) { log.debug("Context class name : " + config.getContextClassName() + " for context " + appInfo.getMetaData().getContextRoot()); } if(config.getContextClassName().equals(SipHostConfig.SIP_CONTEXT_CLASS)) { String objectNameS = config.getCatalinaDomain() + ":j2eeType=WebModule,name=//" + ((hostName == null) ? "localhost" : hostName) + appInfo.getMetaData().getContextRoot() + ",J2EEApplication=none,J2EEServer=none"; ObjectName objectName = new ObjectName(objectNameS); String applicationName = (String) server.invoke(objectName, "getApplicationName", new Object[]{}, new String[]{}); SipFactory sipFactoryFacade = (SipFactory) server.invoke(objectName, "getSipFactoryFacade", new Object[]{}, new String[]{}); TimerService timerService = (TimerService) server.invoke(objectName, "getTimerService", new Object[]{}, new String[]{}); SipSessionsUtil sipSessionsUtil = (SipSessionsUtil) server.invoke(objectName, "getSipSessionsUtil", new Object[]{}, new String[]{}); InitialContext iniCtx = new InitialContext(); Context globalEnvCtx = (Context) iniCtx.lookup("java:/"); Context sipSubcontext = Util.createSubcontext(globalEnvCtx,SipNamingContextListener.SIP_SUBCONTEXT); Context applicationNameSubcontext = Util.createSubcontext(sipSubcontext,applicationName); NonSerializableFactory.rebind(applicationNameSubcontext,SipNamingContextListener.SIP_FACTORY_JNDI_NAME, sipFactoryFacade); NonSerializableFactory.rebind(applicationNameSubcontext, SipNamingContextListener.SIP_SESSIONS_UTIL_JNDI_NAME, sipSessionsUtil); NonSerializableFactory.rebind(applicationNameSubcontext,SipNamingContextListener.TIMER_SERVICE_JNDI_NAME, timerService); if(log.isDebugEnabled()) { log.debug("Sip Objects made available to global JNDI under following context : java:sip/" + applicationName + "/<ObjectName>"); } Thread currentThread = Thread.currentThread(); ClassLoader currentLoader = currentThread.getContextClassLoader(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); ClassLoader parent = loader.getParent(); while (parent != null) { parent = parent.getParent(); } currentThread.setContextClassLoader(loader); appInfo.getMetaData().setENCLoader(loader); Context envCtx = (Context) iniCtx.lookup("java:comp/env"); currentThread.setContextClassLoader(currentLoader); sipSubcontext = Util.createSubcontext(envCtx,SipNamingContextListener.SIP_SUBCONTEXT); applicationNameSubcontext = Util.createSubcontext(sipSubcontext,applicationName); NonSerializableFactory.rebind(applicationNameSubcontext,SipNamingContextListener.SIP_FACTORY_JNDI_NAME, sipFactoryFacade); NonSerializableFactory.rebind(applicationNameSubcontext, SipNamingContextListener.SIP_SESSIONS_UTIL_JNDI_NAME, sipSessionsUtil); NonSerializableFactory.rebind(applicationNameSubcontext,SipNamingContextListener.TIMER_SERVICE_JNDI_NAME, timerService); if(log.isDebugEnabled()) { log.debug("Sip Objects made available to global JNDI under following conetxt : java:comp/env/sip/" + applicationName + "/<ObjectName>"); } } } @Override protected void performUndeployInternal(String hostName, String warUrl, WebApplication appInfo) throws Exception { if(config.getContextClassName().equals(SipHostConfig.SIP_CONTEXT_CLASS)) { // Removing the SipFatcory, SipSessionsUtil and TimerService for the current context being undeployed // from the global JNDI context for other JEE components // TODO fix this to make them disappear from the private ENC and not the global JNDI context String objectNameS = config.getCatalinaDomain() + ":j2eeType=WebModule,name=//" + ((hostName == null) ? "localhost" : hostName) + appInfo.getMetaData().getContextRoot() + ",J2EEApplication=none,J2EEServer=none"; ObjectName objectName = new ObjectName(objectNameS); if(server.isRegistered(objectName)) { String applicationName = (String) server.invoke(objectName, "getApplicationName", new Object[]{}, new String[]{}); try { InitialContext iniCtx = new InitialContext(); Context applicationNameEnvCtx = (Context) iniCtx.lookup("java:/sip/" + applicationName); Util.unbind(applicationNameEnvCtx,SipNamingContextListener.SIP_FACTORY_JNDI_NAME); Util.unbind(applicationNameEnvCtx, SipNamingContextListener.SIP_SESSIONS_UTIL_JNDI_NAME); Util.unbind(applicationNameEnvCtx,SipNamingContextListener.TIMER_SERVICE_JNDI_NAME); Context sipEnvCtx = (Context) iniCtx.lookup("java:/sip/"); Util.unbind(sipEnvCtx, applicationName); } catch (OperationNotSupportedException onse) { log.warn("Could not remove the JNDI context java:/sip/" + applicationName + ", cause " + onse.getMessage()); } catch (NameNotFoundException nnfe) { log.warn("Could not remove the JNDI context java:/sip/" + applicationName + ", cause " + nnfe.getMessage()); } } } super.performUndeployInternal(hostName, warUrl, appInfo); } }