private static void addServlets(JBossWebMetaData jbwebMD, StandardContext context) { for (JBossServletMetaData smd : jbwebMD.getServlets()) { final String sc = smd.getServletClass(); if (sc.equals(WSFServlet.class.getName())) { final String servletName = smd.getServletName(); List<ParamValueMetaData> params = smd.getInitParam(); List<String> urlPatterns = null; for (ServletMappingMetaData smmd : jbwebMD.getServletMappings()) { if (smmd.getServletName().equals(servletName)) { urlPatterns = smmd.getUrlPatterns(); break; } } WSFServlet wsfs = new WSFServlet(); Wrapper wsfsWrapper = context.createWrapper(); wsfsWrapper.setName(servletName); wsfsWrapper.setServlet(wsfs); wsfsWrapper.setServletClass(WSFServlet.class.getName()); for (ParamValueMetaData param : params) { wsfsWrapper.addInitParameter(param.getParamName(), param.getParamValue()); } context.addChild(wsfsWrapper); for (String urlPattern : urlPatterns) { context.addServletMapping(urlPattern, servletName); } } } }
public static boolean servletMappingsExist(JBossWebMetaData webdata, String servletName) { List<ServletMappingMetaData> mappings = webdata.getServletMappings(); if (mappings == null) return false; for (ServletMappingMetaData mapping : mappings) { if (mapping.getServletName().equals(servletName)) { return true; } } return false; }
public static ServletMappingMetaData parse( XMLStreamReader reader, PropertyReplacer propertyReplacer) throws XMLStreamException { ServletMappingMetaData servletMapping = new ServletMappingMetaData(); // Handle attributes final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (attributeHasNamespace(reader, i)) { continue; } final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case ID: { servletMapping.setId(value); break; } default: throw unexpectedAttribute(reader, i); } } // Handle elements while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch (element) { case SERVLET_NAME: servletMapping.setServletName(getElementText(reader, propertyReplacer)); break; case URL_PATTERN: List<String> urlPatterns = servletMapping.getUrlPatterns(); if (urlPatterns == null) { urlPatterns = new ArrayList<String>(); servletMapping.setUrlPatterns(urlPatterns); } urlPatterns.add(getElementText(reader, propertyReplacer)); break; default: throw unexpectedElement(reader); } } return servletMapping; }
@Override public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); if (!JaxrsDeploymentMarker.isJaxrsDeployment(deploymentUnit)) { return; } if (!DeploymentTypeMarker.isType(DeploymentType.WAR, deploymentUnit)) { return; } final DeploymentUnit parent = deploymentUnit.getParent() == null ? deploymentUnit : deploymentUnit.getParent(); final WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY); final JBossWebMetaData webdata = warMetaData.getMergedJBossWebMetaData(); final ResteasyDeploymentData resteasy = deploymentUnit.getAttachment(JaxrsAttachments.RESTEASY_DEPLOYMENT_DATA); if (resteasy == null) return; // remove the resteasy.scan parameter // because it is not needed final List<ParamValueMetaData> params = webdata.getContextParams(); if (params != null) { Iterator<ParamValueMetaData> it = params.iterator(); while (it.hasNext()) { final ParamValueMetaData param = it.next(); if (param.getParamName().equals(RESTEASY_SCAN)) { it.remove(); } else if (param.getParamName().equals(RESTEASY_SCAN_RESOURCES)) { it.remove(); } else if (param.getParamName().equals(RESTEASY_SCAN_PROVIDERS)) { it.remove(); } } } final Map<ModuleIdentifier, ResteasyDeploymentData> attachmentMap = parent.getAttachment(JaxrsAttachments.ADDITIONAL_RESTEASY_DEPLOYMENT_DATA); final List<ResteasyDeploymentData> additionalData = new ArrayList<ResteasyDeploymentData>(); final ModuleSpecification moduleSpec = deploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION); if (moduleSpec != null && attachmentMap != null) { final Set<ModuleIdentifier> identifiers = new HashSet<ModuleIdentifier>(); for (ModuleDependency dep : moduleSpec.getAllDependencies()) { // make sure we don't double up if (!identifiers.contains(dep.getIdentifier())) { identifiers.add(dep.getIdentifier()); if (attachmentMap.containsKey(dep.getIdentifier())) { additionalData.add(attachmentMap.get(dep.getIdentifier())); } } } resteasy.merge(additionalData); } if (!resteasy.getScannedResourceClasses().isEmpty()) { StringBuffer buf = null; for (String resource : resteasy.getScannedResourceClasses()) { if (buf == null) { buf = new StringBuffer(); buf.append(resource); } else { buf.append(",").append(resource); } } String resources = buf.toString(); JAXRS_LOGGER.debugf("Adding JAX-RS resource classes: %s", resources); setContextParameter(webdata, ResteasyContextParameters.RESTEASY_SCANNED_RESOURCES, resources); } if (!resteasy.getScannedProviderClasses().isEmpty()) { StringBuffer buf = null; for (String provider : resteasy.getScannedProviderClasses()) { if (buf == null) { buf = new StringBuffer(); buf.append(provider); } else { buf.append(",").append(provider); } } String providers = buf.toString(); JAXRS_LOGGER.debugf("Adding JAX-RS provider classes: %s", providers); setContextParameter(webdata, ResteasyContextParameters.RESTEASY_SCANNED_PROVIDERS, providers); } if (!resteasy.getScannedJndiComponentResources().isEmpty()) { StringBuffer buf = null; for (String resource : resteasy.getScannedJndiComponentResources()) { if (buf == null) { buf = new StringBuffer(); buf.append(resource); } else { buf.append(",").append(resource); } } String providers = buf.toString(); JAXRS_LOGGER.debugf("Adding JAX-RS jndi component resource classes: %s", providers); setContextParameter( webdata, ResteasyContextParameters.RESTEASY_SCANNED_JNDI_RESOURCES, providers); } if (!resteasy.isUnwrappedExceptionsParameterSet()) { setContextParameter( webdata, ResteasyContextParameters.RESTEASY_UNWRAPPED_EXCEPTIONS, "javax.ejb.EJBException"); } if (resteasy.hasBootClasses() || resteasy.isDispatcherCreated()) return; boolean useScannedClass = false; String servletName; if (resteasy.getScannedApplicationClass() == null) { // if there is no scanned application we must add a servlet with a name of // javax.ws.rs.core.Application JBossServletMetaData servlet = new JBossServletMetaData(); servlet.setName(JAX_RS_SERVLET_NAME); servlet.setServletClass(HttpServlet30Dispatcher.class.getName()); servlet.setAsyncSupported(true); addServlet(webdata, servlet); servletName = JAX_RS_SERVLET_NAME; } else { if (servletMappingsExist(webdata, JAX_RS_SERVLET_NAME)) { throw new DeploymentUnitProcessingException(MESSAGES.conflictUrlMapping()); } // now there are two options. // if there is already a servlet defined with an init param // we don't do anything. // Otherwise we install our filter // JAVA-RS seems somewhat confused about the difference between a context param // and an init param. ParamValueMetaData param = findInitParam(webdata, SERVLET_INIT_PARAM); if (param != null) { // we need to promote the init param to a context param servletName = param.getParamValue(); setContextParameter(webdata, "javax.ws.rs.Application", servletName); } else { ParamValueMetaData contextParam = findContextParam(webdata, "javax.ws.rs.Application"); if (contextParam == null) { setContextParameter( webdata, "javax.ws.rs.Application", resteasy.getScannedApplicationClass().getName()); useScannedClass = true; servletName = resteasy.getScannedApplicationClass().getName(); } else { servletName = contextParam.getParamValue(); } } } boolean mappingSet = false; if (useScannedClass) { // look for servlet mappings if (!servletMappingsExist(webdata, servletName)) { // no mappings, add our own List<String> patterns = new ArrayList<String>(); if (resteasy.getScannedApplicationClass().isAnnotationPresent(ApplicationPath.class)) { ApplicationPath path = resteasy.getScannedApplicationClass().getAnnotation(ApplicationPath.class); String pathValue = path.value().trim(); if (!pathValue.startsWith("/")) { pathValue = "/" + pathValue; } String prefix = pathValue; if (pathValue.endsWith("/")) { pathValue += "*"; } else { pathValue += "/*"; } patterns.add(pathValue); setContextParameter(webdata, "resteasy.servlet.mapping.prefix", prefix); mappingSet = true; } else { JAXRS_LOGGER.noServletMappingFound(servletName); return; } ServletMappingMetaData mapping = new ServletMappingMetaData(); mapping.setServletName(servletName); mapping.setUrlPatterns(patterns); if (webdata.getServletMappings() == null) { webdata.setServletMappings(new ArrayList<ServletMappingMetaData>()); } webdata.getServletMappings().add(mapping); } // add a servlet named after the application class JBossServletMetaData servlet = new JBossServletMetaData(); servlet.setName(servletName); servlet.setServletClass(HttpServlet30Dispatcher.class.getName()); servlet.setAsyncSupported(true); addServlet(webdata, servlet); } if (!mappingSet) { // now we need tell resteasy it's relative path final List<ServletMappingMetaData> mappings = webdata.getServletMappings(); if (mappings != null) { for (final ServletMappingMetaData mapping : mappings) { if (mapping.getServletName().equals(servletName)) { if (mapping.getUrlPatterns() != null) { for (String pattern : mapping.getUrlPatterns()) { if (mappingSet) { JAXRS_LOGGER.moreThanOneServletMapping(servletName, pattern); } else { mappingSet = true; String realPattern = pattern; if (realPattern.endsWith("*")) { realPattern = realPattern.substring(0, realPattern.length() - 1); } setContextParameter(webdata, "resteasy.servlet.mapping.prefix", realPattern); } } } } } } } }
private DeploymentInfo createServletConfig( final JBossWebMetaData mergedMetaData, final DeploymentUnit deploymentUnit, final Module module, final DeploymentClassIndex classReflectionIndex, final WebInjectionContainer injectionContainer, final ComponentRegistry componentRegistry, final ScisMetaData scisMetaData, final VirtualFile deploymentRoot) throws DeploymentUnitProcessingException { try { mergedMetaData.resolveAnnotations(); final DeploymentInfo d = new DeploymentInfo(); d.setContextPath(mergedMetaData.getContextRoot()); if (mergedMetaData.getDescriptionGroup() != null) { d.setDisplayName(mergedMetaData.getDescriptionGroup().getDisplayName()); } d.setDeploymentName(deploymentUnit.getName()); d.setResourceLoader(new DeploymentResourceLoader(deploymentRoot)); d.setClassLoader(module.getClassLoader()); final String servletVersion = mergedMetaData.getServletVersion(); if (servletVersion != null) { d.setMajorVersion(Integer.parseInt(servletVersion.charAt(0) + "")); d.setMinorVersion(Integer.parseInt(servletVersion.charAt(2) + "")); } else { d.setMajorVersion(3); d.setMinorVersion(1); } // for 2.2 apps we do not require a leading / in path mappings boolean is22OrOlder; if (d.getMajorVersion() == 1) { is22OrOlder = true; } else if (d.getMajorVersion() == 2) { is22OrOlder = d.getMinorVersion() < 3; } else { is22OrOlder = false; } HashMap<String, TagLibraryInfo> tldInfo = createTldsInfo(deploymentUnit, classReflectionIndex, componentRegistry, d); HashMap<String, JspPropertyGroup> propertyGroups = createJspConfig(mergedMetaData); JspServletBuilder.setupDeployment( d, propertyGroups, tldInfo, new UndertowJSPInstanceManager(injectionContainer)); d.setJspConfigDescriptor( new JspConfigDescriptorImpl(tldInfo.values(), propertyGroups.values())); d.setDefaultServletConfig(new DefaultServletConfig(true, Collections.<String>emptySet())); // default JSP servlet final ServletInfo jspServlet = new ServletInfo("Default JSP Servlet", JspServlet.class) .addMapping("*.jsp") .addMapping("*.jspx") .addInitParam("development", "false"); // todo: make configurable d.addServlet(jspServlet); final Set<String> jspPropertyGroupMappings = propertyGroups.keySet(); for (final String mapping : jspPropertyGroupMappings) { jspServlet.addMapping(mapping); } d.setClassIntrospecter(new ComponentClassIntrospector(componentRegistry)); final Map<String, List<ServletMappingMetaData>> servletMappings = new HashMap<>(); if (mergedMetaData.getServletMappings() != null) { for (final ServletMappingMetaData mapping : mergedMetaData.getServletMappings()) { List<ServletMappingMetaData> list = servletMappings.get(mapping.getServletName()); if (list == null) { servletMappings.put(mapping.getServletName(), list = new ArrayList<>()); } list.add(mapping); } } final Set<String> seenMappings = new HashSet<>(jspPropertyGroupMappings); if (mergedMetaData.getServlets() != null) { for (final JBossServletMetaData servlet : mergedMetaData.getServlets()) { final ServletInfo s; if (servlet.getJspFile() != null) { // TODO: real JSP support s = new ServletInfo(servlet.getName(), JspServlet.class); s.addHandlerChainWrapper(new JspFileWrapper(servlet.getJspFile())); } else { Class<? extends Servlet> servletClass = (Class<? extends Servlet>) classReflectionIndex.classIndex(servlet.getServletClass()).getModuleClass(); ComponentRegistry.ComponentManagedReferenceFactory creator = componentRegistry.getComponentsByClass().get(servletClass); if (creator != null) { InstanceFactory<Servlet> factory = createInstanceFactory(creator); s = new ServletInfo(servlet.getName(), servletClass, factory); } else { s = new ServletInfo(servlet.getName(), servletClass); } } s.setAsyncSupported(servlet.isAsyncSupported()) .setJspFile(servlet.getJspFile()) .setEnabled(servlet.isEnabled()); if (servlet.getRunAs() != null) { s.setRunAs(servlet.getRunAs().getRoleName()); } if (servlet .getLoadOnStartupSet()) { // todo why not cleanup api and just use int everywhere s.setLoadOnStartup(servlet.getLoadOnStartupInt()); } List<ServletMappingMetaData> mappings = servletMappings.get(servlet.getName()); if (mappings != null) { for (ServletMappingMetaData mapping : mappings) { for (String pattern : mapping.getUrlPatterns()) { if (is22OrOlder && !pattern.startsWith("*") && !pattern.startsWith("/")) { pattern = "/" + pattern; } if (!seenMappings.contains(pattern)) { s.addMapping(pattern); seenMappings.add(pattern); } } } } if (servlet.getInitParam() != null) { for (ParamValueMetaData initParam : servlet.getInitParam()) { if (!s.getInitParams().containsKey(initParam.getParamName())) { s.addInitParam(initParam.getParamName(), initParam.getParamValue()); } } } if (servlet.getServletSecurity() != null) { ServletSecurityInfo securityInfo = new ServletSecurityInfo(); s.setServletSecurityInfo(securityInfo); securityInfo .setEmptyRoleSemantic( servlet.getServletSecurity().getEmptyRoleSemantic() == EmptyRoleSemanticType.PERMIT ? PERMIT : DENY) .setTransportGuaranteeType( transportGuaranteeType(servlet.getServletSecurity().getTransportGuarantee())) .addRolesAllowed(servlet.getServletSecurity().getRolesAllowed()); if (servlet.getServletSecurity().getHttpMethodConstraints() != null) { for (HttpMethodConstraintMetaData method : servlet.getServletSecurity().getHttpMethodConstraints()) { securityInfo.addHttpMethodSecurityInfo( new HttpMethodSecurityInfo() .setEmptyRoleSemantic( method.getEmptyRoleSemantic() == EmptyRoleSemanticType.PERMIT ? PERMIT : DENY) .setTransportGuaranteeType( transportGuaranteeType(method.getTransportGuarantee())) .addRolesAllowed(method.getRolesAllowed()) .setMethod(method.getMethod())); } } } if (servlet.getSecurityRoleRefs() != null) { for (final SecurityRoleRefMetaData ref : servlet.getSecurityRoleRefs()) { s.addSecurityRoleRef(ref.getRoleName(), ref.getRoleLink()); } } d.addServlet(s); } } if (mergedMetaData.getFilters() != null) { for (final FilterMetaData filter : mergedMetaData.getFilters()) { Class<? extends Filter> filterClass = (Class<? extends Filter>) classReflectionIndex.classIndex(filter.getFilterClass()).getModuleClass(); ComponentRegistry.ComponentManagedReferenceFactory creator = componentRegistry.getComponentsByClass().get(filterClass); FilterInfo f; if (creator != null) { InstanceFactory<Filter> instanceFactory = createInstanceFactory(creator); f = new FilterInfo(filter.getName(), filterClass, instanceFactory); } else { f = new FilterInfo(filter.getName(), filterClass); } f.setAsyncSupported(filter.isAsyncSupported()); d.addFilter(f); if (filter.getInitParam() != null) { for (ParamValueMetaData initParam : filter.getInitParam()) { f.addInitParam(initParam.getParamName(), initParam.getParamValue()); } } } } if (mergedMetaData.getFilterMappings() != null) { for (final FilterMappingMetaData mapping : mergedMetaData.getFilterMappings()) { if (mapping.getUrlPatterns() != null) { for (String url : mapping.getUrlPatterns()) { if (is22OrOlder && !url.startsWith("*") && !url.startsWith("/")) { url = "/" + url; } if (mapping.getDispatchers() != null && !mapping.getDispatchers().isEmpty()) { for (DispatcherType dispatcher : mapping.getDispatchers()) { d.addFilterUrlMapping( mapping.getFilterName(), url, javax.servlet.DispatcherType.valueOf(dispatcher.name())); } } else { d.addFilterUrlMapping( mapping.getFilterName(), url, javax.servlet.DispatcherType.REQUEST); } } } if (mapping.getServletNames() != null) { for (String servletName : mapping.getServletNames()) { if (mapping.getDispatchers() != null && !mapping.getDispatchers().isEmpty()) { for (DispatcherType dispatcher : mapping.getDispatchers()) { d.addFilterServletNameMapping( mapping.getFilterName(), servletName, javax.servlet.DispatcherType.valueOf(dispatcher.name())); } } else { d.addFilterServletNameMapping( mapping.getFilterName(), servletName, javax.servlet.DispatcherType.REQUEST); } } } } } if (scisMetaData != null && scisMetaData.getHandlesTypes() != null) { for (final Map.Entry<ServletContainerInitializer, Set<Class<?>>> sci : scisMetaData.getHandlesTypes().entrySet()) { final ImmediateInstanceFactory<ServletContainerInitializer> instanceFactory = new ImmediateInstanceFactory<>(sci.getKey()); d.addServletContainerInitalizer( new ServletContainerInitializerInfo( sci.getKey().getClass(), instanceFactory, sci.getValue())); } } if (mergedMetaData.getListeners() != null) { for (ListenerMetaData listener : mergedMetaData.getListeners()) { addListener(classReflectionIndex, componentRegistry, d, listener); } } if (mergedMetaData.getContextParams() != null) { for (ParamValueMetaData param : mergedMetaData.getContextParams()) { d.addInitParameter(param.getParamName(), param.getParamValue()); } } if (mergedMetaData.getWelcomeFileList() != null && mergedMetaData.getWelcomeFileList().getWelcomeFiles() != null) { d.addWelcomePages(mergedMetaData.getWelcomeFileList().getWelcomeFiles()); } else { d.addWelcomePages("index.html", "index.htm", "index.jsp"); } if (mergedMetaData.getErrorPages() != null) { for (final ErrorPageMetaData page : mergedMetaData.getErrorPages()) { final ErrorPage errorPage; if (page.getExceptionType() == null || page.getExceptionType().isEmpty()) { errorPage = new ErrorPage(page.getLocation(), Integer.parseInt(page.getErrorCode())); } else { errorPage = new ErrorPage( page.getLocation(), (Class<? extends Throwable>) classReflectionIndex.classIndex(page.getExceptionType()).getModuleClass()); } d.addErrorPages(errorPage); } } if (mergedMetaData.getMimeMappings() != null) { for (final MimeMappingMetaData mapping : mergedMetaData.getMimeMappings()) { d.addMimeMapping(new MimeMapping(mapping.getExtension(), mapping.getMimeType())); } } if (mergedMetaData.getSecurityConstraints() != null) { for (SecurityConstraintMetaData constraint : mergedMetaData.getSecurityConstraints()) { SecurityConstraint securityConstraint = new SecurityConstraint() .setTransportGuaranteeType( transportGuaranteeType(constraint.getTransportGuarantee())) .addRolesAllowed(constraint.getRoleNames()); if (constraint.getAuthConstraint() == null) { // no auth constraint means we permit the empty roles securityConstraint.setEmptyRoleSemantic(PERMIT); } if (constraint.getResourceCollections() != null) { for (final WebResourceCollectionMetaData resourceCollection : constraint.getResourceCollections()) { securityConstraint.addWebResourceCollection( new WebResourceCollection() .addHttpMethods(resourceCollection.getHttpMethods()) .addHttpMethodOmissions(resourceCollection.getHttpMethodOmissions()) .addUrlPatterns(resourceCollection.getUrlPatterns())); } } d.addSecurityConstraint(securityConstraint); } } final LoginConfigMetaData loginConfig = mergedMetaData.getLoginConfig(); if (loginConfig != null) { String authMethod = authMethod(loginConfig.getAuthMethod()); if (loginConfig.getFormLoginConfig() != null) { d.setLoginConfig( new LoginConfig( authMethod, loginConfig.getRealmName(), loginConfig.getFormLoginConfig().getLoginPage(), loginConfig.getFormLoginConfig().getErrorPage())); } else { d.setLoginConfig(new LoginConfig(authMethod, loginConfig.getRealmName())); } } d.addSecurityRoles(mergedMetaData.getSecurityRoleNames()); if (mergedMetaData.getSecurityDomain() != null) { String contextId = deploymentUnit.getName(); if (deploymentUnit.getParent() != null) { contextId = deploymentUnit.getParent().getName() + "!" + contextId; } d.addOuterHandlerChainWrapper( SecurityContextCreationHandler.wrapper(mergedMetaData.getSecurityDomain())); d.addDispatchedHandlerChainWrapper( SecurityContextAssociationHandler.wrapper( mergedMetaData.getPrincipalVersusRolesMap(), contextId)); } // Setup an deployer configured ServletContext attributes final List<ServletContextAttribute> attributes = deploymentUnit.getAttachmentList(ServletContextAttribute.ATTACHMENT_KEY); for (ServletContextAttribute attribute : attributes) { d.addServletContextAttribute(attribute.getName(), attribute.getValue()); } if (mergedMetaData.getLocalEncodings() != null && mergedMetaData.getLocalEncodings().getMappings() != null) { for (LocaleEncodingMetaData locale : mergedMetaData.getLocalEncodings().getMappings()) { d.addLocaleCharsetMapping(locale.getLocale(), locale.getEncoding()); } } return d; } catch (ClassNotFoundException e) { throw new DeploymentUnitProcessingException(e); } }