@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); } } } } } } } }
protected void scan( final DeploymentUnit du, final ClassLoader classLoader, final ResteasyDeploymentData resteasyDeploymentData) throws DeploymentUnitProcessingException, ModuleLoadException { final CompositeIndex index = du.getAttachment(Attachments.COMPOSITE_ANNOTATION_INDEX); if (!resteasyDeploymentData.shouldScan()) { return; } final Set<ClassInfo> applicationClass = index.getAllKnownSubclasses(APPLICATION); try { if (applicationClass.size() > 1) { StringBuilder builder = new StringBuilder(); Set<ClassInfo> aClasses = new HashSet<ClassInfo>(); for (ClassInfo c : applicationClass) { if (!Modifier.isAbstract(c.flags())) { aClasses.add(c); } builder.append(" ").append(c.name().toString()); } if (aClasses.size() > 1) { throw new DeploymentUnitProcessingException( MESSAGES.onlyOneApplicationClassAllowed(builder)); } else if (aClasses.size() == 1) { ClassInfo aClass = applicationClass.iterator().next(); resteasyDeploymentData.setScannedApplicationClass( (Class<? extends Application>) classLoader.loadClass(aClass.name().toString())); } } else if (applicationClass.size() == 1) { ClassInfo aClass = applicationClass.iterator().next(); resteasyDeploymentData.setScannedApplicationClass( (Class<? extends Application>) classLoader.loadClass(aClass.name().toString())); } } catch (ClassNotFoundException e) { throw MESSAGES.cannotLoadApplicationClass(e); } List<AnnotationInstance> resources = null; List<AnnotationInstance> providers = null; if (resteasyDeploymentData.isScanResources()) { resources = index.getAnnotations(JaxrsAnnotations.PATH.getDotName()); } if (resteasyDeploymentData.isScanProviders()) { providers = index.getAnnotations(JaxrsAnnotations.PROVIDER.getDotName()); } if ((resources == null || resources.isEmpty()) && (providers == null || providers.isEmpty())) return; final Set<ClassInfo> pathInterfaces = new HashSet<ClassInfo>(); if (resources != null) { for (AnnotationInstance e : resources) { final ClassInfo info; if (e.target() instanceof ClassInfo) { info = (ClassInfo) e.target(); } else if (e.target() instanceof MethodInfo) { // ignore continue; } else { JAXRS_LOGGER.classOrMethodAnnotationNotFound("@Path", e.target()); continue; } if (!Modifier.isInterface(info.flags())) { resteasyDeploymentData.getScannedResourceClasses().add(info.name().toString()); } else { pathInterfaces.add(info); } } } if (providers != null) { for (AnnotationInstance e : providers) { if (e.target() instanceof ClassInfo) { ClassInfo info = (ClassInfo) e.target(); if (!Modifier.isInterface(info.flags())) { resteasyDeploymentData.getScannedProviderClasses().add(info.name().toString()); } } else { JAXRS_LOGGER.classAnnotationNotFound("@Provider", e.target()); } } } // look for all implementations of interfaces annotated @Path for (final ClassInfo iface : pathInterfaces) { final Set<ClassInfo> implementors = index.getAllKnownImplementors(iface.name()); for (final ClassInfo implementor : implementors) { resteasyDeploymentData.getScannedResourceClasses().add(implementor.name().toString()); } } }
@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()); } } }