@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); } } } } } } } }
@Override public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); final Module module = deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.MODULE); if (module == null) { return; } final ResteasyDeploymentData resteasy = deploymentUnit.getAttachment(JaxrsAttachments.RESTEASY_DEPLOYMENT_DATA); if (resteasy == null) { return; } // right now I only support resources if (!resteasy.isScanResources()) return; final EEModuleDescription moduleDescription = deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION); if (moduleDescription == null) { return; } final ClassLoader loader = module.getClassLoader(); for (final ComponentDescription component : moduleDescription.getComponentDescriptions()) { Class<?> componentClass = null; try { componentClass = loader.loadClass(component.getComponentClassName()); } catch (ClassNotFoundException e) { throw new DeploymentUnitProcessingException(e); } if (!GetRestful.isRootResource(componentClass)) continue; if (component instanceof SessionBeanComponentDescription) { Class[] jaxrsType = GetRestful.getSubResourceClass(componentClass); final String jndiName; if (component.getViews().size() == 1) { // only 1 view, just use the simple JNDI name jndiName = "java:app/" + moduleDescription.getModuleName() + "/" + component.getComponentName(); } else { boolean found = false; String foundType = null; for (final ViewDescription view : component.getViews()) { for (Class subResource : jaxrsType) { if (view.getViewClassName().equals(subResource.getName())) { foundType = subResource.getName(); found = true; break; } } if (found) { break; } } if (!found) { throw JaxrsMessages.MESSAGES.typeNameNotAnEjbView( Arrays.asList(jaxrsType), component.getComponentName()); } jndiName = "java:app/" + moduleDescription.getModuleName() + "/" + component.getComponentName() + "!" + foundType; } JAXRS_LOGGER.debugf( "Found JAX-RS Managed Bean: %s local jndi jaxRsTypeName: %s", component.getComponentClassName(), jndiName); StringBuilder buf = new StringBuilder(); buf.append(jndiName) .append(";") .append(component.getComponentClassName()) .append(";") .append("true"); resteasy.getScannedJndiComponentResources().add(buf.toString()); // make sure its removed from list resteasy.getScannedResourceClasses().remove(component.getComponentClassName()); } else if (component instanceof ManagedBeanComponentDescription) { String jndiName = "java:app/" + moduleDescription.getModuleName() + "/" + component.getComponentName(); JAXRS_LOGGER.debugf( "Found JAX-RS Managed Bean: %s local jndi name: %s", component.getComponentClassName(), jndiName); StringBuilder buf = new StringBuilder(); buf.append(jndiName) .append(";") .append(component.getComponentClassName()) .append(";") .append("true"); resteasy.getScannedJndiComponentResources().add(buf.toString()); // make sure its removed from list resteasy.getScannedResourceClasses().remove(component.getComponentClassName()); } } }