/* * 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 java.util.Iterator; import java.util.List; import org.apache.catalina.core.StandardWrapper; import org.apache.log4j.Logger; import org.jboss.metadata.javaee.spec.DescriptionGroupMetaData; import org.jboss.metadata.javaee.spec.DescriptionImpl; import org.jboss.metadata.javaee.spec.DescriptionsImpl; import org.jboss.metadata.javaee.spec.DisplayNameImpl; import org.jboss.metadata.javaee.spec.DisplayNamesImpl; import org.jboss.metadata.javaee.spec.IconImpl; import org.jboss.metadata.javaee.spec.IconsImpl; import org.jboss.metadata.javaee.spec.SecurityRoleRefMetaData; import org.jboss.metadata.javaee.spec.SecurityRoleRefsMetaData; import org.jboss.metadata.sip.jboss.JBossConvergedSipMetaData; import org.jboss.metadata.sip.jboss.JBossServletsMetaData; import org.jboss.metadata.sip.spec.AndMetaData; import org.jboss.metadata.sip.spec.ConditionMetaData; import org.jboss.metadata.sip.spec.ContainsMetaData; import org.jboss.metadata.sip.spec.EqualMetaData; import org.jboss.metadata.sip.spec.ExistsMetaData; import org.jboss.metadata.sip.spec.ListenerMetaData; import org.jboss.metadata.sip.spec.NotMetaData; import org.jboss.metadata.sip.spec.OrMetaData; import org.jboss.metadata.sip.spec.ParamValueMetaData; import org.jboss.metadata.sip.spec.PatternMetaData; import org.jboss.metadata.sip.spec.ServletMetaData; import org.jboss.metadata.sip.spec.ServletSelectionMetaData; import org.jboss.metadata.sip.spec.SipLoginConfigMetaData; import org.jboss.metadata.sip.spec.SipResourceCollectionMetaData; import org.jboss.metadata.sip.spec.SipResourceCollectionsMetaData; import org.jboss.metadata.sip.spec.SipSecurityConstraintMetaData; import org.jboss.metadata.sip.spec.SipServletMappingMetaData; import org.jboss.metadata.sip.spec.SubdomainOfMetaData; import org.jboss.metadata.web.jboss.JBossWebMetaData; import org.jboss.metadata.web.spec.TransportGuaranteeType; import org.jboss.web.tomcat.service.deployers.JBossContextConfig; import org.mobicents.servlet.sip.startup.SipContext; import org.mobicents.servlet.sip.startup.SipDeploymentException; import org.mobicents.servlet.sip.startup.SipStandardContext; import org.mobicents.servlet.sip.startup.loading.SipLoginConfig; import org.mobicents.servlet.sip.startup.loading.SipSecurityConstraint; import org.mobicents.servlet.sip.startup.loading.SipServletImpl; import org.mobicents.servlet.sip.startup.loading.SipServletMapping; import org.mobicents.servlet.sip.startup.loading.rules.AndRule; import org.mobicents.servlet.sip.startup.loading.rules.ContainsRule; import org.mobicents.servlet.sip.startup.loading.rules.EqualsRule; import org.mobicents.servlet.sip.startup.loading.rules.ExistsRule; import org.mobicents.servlet.sip.startup.loading.rules.MatchingRule; import org.mobicents.servlet.sip.startup.loading.rules.NotRule; import org.mobicents.servlet.sip.startup.loading.rules.OrRule; import org.mobicents.servlet.sip.startup.loading.rules.SubdomainRule; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Startup event listener for a the <b>SipStandardContext</b> that configures * the properties of that Context, and the associated defined servlets. It * extends the JbossContextConfig to be able to load sip servlet applications. * * @author Jean Deruelle * */ public class SipJBossContextConfig extends JBossContextConfig { private static transient Logger logger = Logger.getLogger(SipJBossContextConfig.class); @Override protected void processContextParameters() { super.processContextParameters(); JBossWebMetaData metaData = metaDataLocal.get(); if(metaData instanceof JBossConvergedSipMetaData && context instanceof SipStandardContext) { processSipContextParameters((JBossConvergedSipMetaData)metaData); } } /** * Process the context parameters defined in sip.xml. Let a user application * override the sharedMetaData values. */ protected void processSipContextParameters(JBossConvergedSipMetaData metaData) { if(metaData.getSipContextParams() != null) { for (org.jboss.metadata.sip.spec.ParamValueMetaData param : metaData.getSipContextParams()) { context.addParameter(param.getParamName(), param.getParamValue()); } } } @Override protected void processWebMetaData(JBossWebMetaData metaData) { super.processWebMetaData(metaData); if(metaData instanceof JBossConvergedSipMetaData && context instanceof SipContext) { processSipMetaData((JBossConvergedSipMetaData)metaData); } } /** * @param convergedMetaData */ protected void processSipMetaData(JBossConvergedSipMetaData convergedMetaData) { SipContext convergedContext = (SipContext) context; convergedContext.setWrapperClass(SipServletImpl.class.getName()); /* * sip sepcific treatment */ //description DescriptionGroupMetaData descriptionGroupMetaData = convergedMetaData.getDescriptionGroup(); if(descriptionGroupMetaData != null) { DescriptionsImpl descriptionsImpl = (DescriptionsImpl)descriptionGroupMetaData.getDescriptions(); if(descriptionsImpl != null && !descriptionsImpl.isEmpty()) { convergedContext.setDescription(((DescriptionImpl)descriptionsImpl.iterator().next()).getDescription()); } IconsImpl iconsImpl = (IconsImpl)descriptionGroupMetaData.getIcons(); if(iconsImpl != null && !iconsImpl.isEmpty()) { IconImpl iconImpl = (IconImpl)iconsImpl.iterator().next(); convergedContext.setSmallIcon(iconImpl.getSmallIcon()); convergedContext.setLargeIcon(iconImpl.getLargeIcon()); } DisplayNamesImpl displayNamesImpl = (DisplayNamesImpl)descriptionGroupMetaData.getDisplayNames(); if(displayNamesImpl != null && !displayNamesImpl.isEmpty()) { convergedContext.setDisplayName(((DisplayNameImpl)displayNamesImpl.iterator().next()).getDisplayName()); } } //app name if(convergedMetaData.getApplicationName() == null) { throw new SipDeploymentException("No app-name present in the sip.xml deployment descriptor or no SipApplication annotation defined"); } convergedContext.setApplicationName(convergedMetaData.getApplicationName()); //sip proxy config if(convergedMetaData.getProxyConfig() != null) { convergedContext.setProxyTimeout(convergedMetaData.getProxyConfig().getProxyTimeout()); } //sip session config if(convergedMetaData.getSessionConfig() != null) { convergedContext.setSipApplicationSessionTimeout(convergedMetaData.getSessionConfig().getSessionTimeout()); } //sip security contstraints List<SipSecurityConstraintMetaData> sipConstraintMetaDatas = convergedMetaData.getSipSecurityContraints(); if(sipConstraintMetaDatas != null) { for(SipSecurityConstraintMetaData sipConstraintMetaData : sipConstraintMetaDatas) { SipSecurityConstraint sipSecurityConstraint = new SipSecurityConstraint(); sipSecurityConstraint.setDisplayName(sipConstraintMetaData.getDisplayName()); for(String role : sipConstraintMetaData.getAuthConstraint().getRoleNames()) { sipSecurityConstraint.addAuthRole(role); } if(sipConstraintMetaData.getProxyAuthentication() != null) { sipSecurityConstraint.setProxyAuthentication(true); } TransportGuaranteeType tg = sipConstraintMetaData.getTransportGuarantee(); sipSecurityConstraint.setUserConstraint(tg.name()); SipResourceCollectionsMetaData srcs = sipConstraintMetaData.getResourceCollections(); if (srcs != null) { for (SipResourceCollectionMetaData src : srcs) { org.apache.catalina.deploy.SecurityCollection securityCollection = new org.apache.catalina.deploy.SecurityCollection(); securityCollection.setName(src.getName()); List<String> methods = src.getSipMethods(); if (methods != null) { for (String method : src.getSipMethods()) { securityCollection.addMethod(method); } } List<String> servletNames = src.getServletNames(); if (servletNames != null) { for (String servletName : servletNames) { securityCollection.addPattern(servletName); } } sipSecurityConstraint.addCollection(securityCollection); } } } } //sip login config SipLoginConfigMetaData sipLoginConfig = convergedMetaData.getSipLoginConfig(); if (sipLoginConfig != null) { SipLoginConfig sipLoginConfig2 = new SipLoginConfig(); sipLoginConfig2.setAuthMethod(sipLoginConfig.getAuthMethod()); sipLoginConfig2.setRealmName(sipLoginConfig.getRealmName()); sipLoginConfig2.addIdentityAssertion(sipLoginConfig.getIdentityAssertion().getIdentityAssertionScheme(), sipLoginConfig.getIdentityAssertion().getIdentityAssertionSupport()); convergedContext.setSipLoginConfig(sipLoginConfig2); } //Sip Listeners List<ListenerMetaData> sipListeners = convergedMetaData.getSipListeners(); if (sipListeners != null) { for (ListenerMetaData value : sipListeners) { convergedContext.addSipApplicationListener(value.getListenerClass()); } } //servlet selection boolean servletSelectionSet = false; ServletSelectionMetaData servletSelectionMetaData = convergedMetaData.getServletSelection(); if(servletSelectionMetaData != null) { String mainServlet = servletSelectionMetaData.getMainServlet(); if(mainServlet != null && mainServlet.length() > 0) { convergedContext.setMainServlet(mainServlet); servletSelectionSet = true; } if(servletSelectionMetaData.getSipServletMappings() != null && servletSelectionMetaData.getSipServletMappings().size() > 0) { if(servletSelectionSet) { throw new SipDeploymentException("the main servlet and servlet mapping cannot be present at the same time in sip.xml or as annotations !"); } Iterator<SipServletMappingMetaData> sipServletMapping = servletSelectionMetaData.getSipServletMappings().iterator(); while (sipServletMapping.hasNext()) { SipServletMappingMetaData sipServletMappingMetaData = (SipServletMappingMetaData) sipServletMapping .next(); SipServletMapping sipMapping = new SipServletMapping(); sipMapping.setServletName(sipServletMappingMetaData.getServletName()); PatternMetaData pattern = sipServletMappingMetaData.getPattern(); MatchingRule matchingRule = buildRule(pattern.getCondition()); sipMapping.setMatchingRule(matchingRule); convergedContext.addSipServletMapping(sipMapping); } servletSelectionSet = true; } if(servletSelectionMetaData.getSipRubyController() != null) { convergedContext.setSipRubyController(servletSelectionMetaData.getSipRubyController()); servletSelectionSet = true; } } //Sip Servlet JBossServletsMetaData sipServlets = convergedMetaData.getSipServlets(); if (sipServlets != null) { if(sipServlets.size() > 1 && !servletSelectionSet) { throw new SipDeploymentException("the main servlet is not set and there is more than one servlet defined in the sip.xml or as annotations !"); } for (ServletMetaData value : sipServlets) { SipServletImpl wrapper = (SipServletImpl)convergedContext.createWrapper(); wrapper.setName(value.getName()); // no main servlet defined in the sip.xml we take the name of the only sip servlet present if(!servletSelectionSet) { convergedContext.setMainServlet(value.getName()); } wrapper.setServletClass(value.getServletClass()); wrapper.setServletName(value.getServletName()); if (value.getJspFile() != null) { wrapper.setJspFile(value.getJspFile()); } wrapper.setLoadOnStartup(value.getLoadOnStartup()); if (value.getRunAs() != null) { wrapper.setRunAs(value.getRunAs().getRoleName()); } List<? extends ParamValueMetaData> params = value.getInitParam(); if (params != null) { for (ParamValueMetaData param : params) { wrapper.addInitParameter(param.getParamName(), param .getParamValue()); } } SecurityRoleRefsMetaData refs = value.getSecurityRoleRefs(); if (refs != null) { for (SecurityRoleRefMetaData ref : refs) { wrapper.addSecurityReference(ref.getRoleName(), ref .getRoleLink()); } } convergedContext.addChild((SipServletImpl)wrapper); } } convergedContext.setSipApplicationKeyMethod(convergedMetaData.getSipApplicationKeyMethod()); convergedContext.setConcurrencyControlMode(convergedMetaData.getConcurrencyControlMode()); convergedContext.setWrapperClass(StandardWrapper.class.getName()); } public static MatchingRule buildRule(ConditionMetaData condition) { if (condition instanceof AndMetaData) { AndMetaData andMetaData = (AndMetaData) condition; AndRule and = new AndRule(); List<ConditionMetaData> list = andMetaData.getConditions(); for(ConditionMetaData newCondition : list) { and.addCriterion(buildRule(newCondition)); } return and; } else if (condition instanceof EqualMetaData) { EqualMetaData equalMetaData = (EqualMetaData) condition; String var = equalMetaData.getVar(); String value = equalMetaData.getValue(); boolean ignoreCase = equalMetaData.isIgnoreCase(); return new EqualsRule(var, value, ignoreCase); } else if (condition instanceof SubdomainOfMetaData) { SubdomainOfMetaData subdomainOfMetaData = (SubdomainOfMetaData) condition; String var = subdomainOfMetaData.getVar(); String value = subdomainOfMetaData.getValue(); return new SubdomainRule(var, value); } else if (condition instanceof OrMetaData) { OrMetaData orMetaData = (OrMetaData) condition; OrRule or = new OrRule(); List<ConditionMetaData> list = orMetaData.getConditions(); for(ConditionMetaData newCondition : list) { or.addCriterion(buildRule(newCondition)); } return or; } else if (condition instanceof NotMetaData) { NotMetaData notMetaData = (NotMetaData) condition; NotRule not = new NotRule(); not.setCriterion(buildRule(notMetaData.getCondition())); return not; } else if (condition instanceof ContainsMetaData) { ContainsMetaData containsMetaData = (ContainsMetaData) condition; String var = containsMetaData.getVar(); String value = containsMetaData.getValue(); boolean ignoreCase = containsMetaData.isIgnoreCase(); return new ContainsRule(var, value, ignoreCase); } else if (condition instanceof ExistsMetaData) { ExistsMetaData existsMetaData = (ExistsMetaData) condition; return new ExistsRule(existsMetaData.getVar()); } else { throw new IllegalArgumentException("Unknown rule: " + condition); } } }