public void deploy(final DeploymentPhaseContext phaseContext)
      throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    final WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
    if (warMetaData == null) {
      return; // Nothing we can do without WarMetaData
    }
    final ResourceRoot deploymentRoot =
        deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.DEPLOYMENT_ROOT);
    if (deploymentRoot == null) {
      return; // We don't have a root to work with
    }

    final DeploymentUnit parent = deploymentUnit.getParent();
    if (parent == null || !DeploymentTypeMarker.isType(DeploymentType.EAR, parent)) {
      return; // Only care if this war is nested in an EAR
    }

    final EarMetaData earMetaData = parent.getAttachment(Attachments.EAR_METADATA);
    if (earMetaData == null) {
      return; // Nothing to see here
    }

    final ModulesMetaData modulesMetaData = earMetaData.getModules();
    if (modulesMetaData != null)
      for (ModuleMetaData moduleMetaData : modulesMetaData) {
        if (Web.equals(moduleMetaData.getType())
            && moduleMetaData.getFileName().equals(deploymentRoot.getRootName())) {
          String contextRoot =
              WebModuleMetaData.class.cast(moduleMetaData.getValue()).getContextRoot();

          if (contextRoot == null
              && (warMetaData.getJBossWebMetaData() == null
                  || warMetaData.getJBossWebMetaData().getContextRoot() == null)) {
            contextRoot =
                "/"
                    + parent.getName().substring(0, parent.getName().length() - 4)
                    + "/"
                    + deploymentUnit.getName().substring(0, deploymentUnit.getName().length() - 4);
          }

          if (contextRoot != null) {
            JBossWebMetaData jBossWebMetaData = warMetaData.getJBossWebMetaData();
            if (jBossWebMetaData == null) {
              jBossWebMetaData = new JBoss70WebMetaData();
              warMetaData.setJBossWebMetaData(jBossWebMetaData);
            }
            jBossWebMetaData.setContextRoot(contextRoot);
          }
          return;
        }
      }
  }
Esempio n. 2
0
 /**
  * Gets the JBossWebMetaData from the WarMetaData attached to the provided deployment unit, if
  * any.
  *
  * @param unit
  * @return the JBossWebMetaData or null if either that or the parent WarMetaData are not found.
  */
 public static JBossWebMetaData getJBossWebMetaData(final DeploymentUnit unit) {
   final WarMetaData warMetaData = getOptionalAttachment(unit, WarMetaData.ATTACHMENT_KEY);
   JBossWebMetaData result = null;
   if (warMetaData != null) {
     result = warMetaData.getMergedJBossWebMetaData();
     if (result == null) {
       result = warMetaData.getJBossWebMetaData();
     }
   } else {
     result = getOptionalAttachment(unit, WSAttachmentKeys.JBOSSWEB_METADATA_KEY);
   }
   return result;
 }
 static String hostNameOfDeployment(final WarMetaData metaData, final String defaultHost) {
   Collection<String> hostNames = null;
   if (metaData.getMergedJBossWebMetaData() != null) {
     hostNames = metaData.getMergedJBossWebMetaData().getVirtualHosts();
   }
   if (hostNames == null || hostNames.isEmpty()) {
     hostNames = Collections.singleton(defaultHost);
   }
   String hostName = hostNames.iterator().next();
   if (hostName == null) {
     throw UndertowLogger.ROOT_LOGGER.nullHostName();
   }
   return hostName;
 }
  @Override
  public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    if (!JaxrsDeploymentMarker.isJaxrsDeployment(deploymentUnit)) {
      return;
    }
    final DeploymentUnit parent =
        deploymentUnit.getParent() == null ? deploymentUnit : deploymentUnit.getParent();
    final Map<ModuleIdentifier, ResteasyDeploymentData> deploymentData;
    if (deploymentUnit.getParent() == null) {
      deploymentData =
          Collections.synchronizedMap(new HashMap<ModuleIdentifier, ResteasyDeploymentData>());
      deploymentUnit.putAttachment(
          JaxrsAttachments.ADDITIONAL_RESTEASY_DEPLOYMENT_DATA, deploymentData);
    } else {
      deploymentData = parent.getAttachment(JaxrsAttachments.ADDITIONAL_RESTEASY_DEPLOYMENT_DATA);
    }

    final ModuleIdentifier moduleIdentifier =
        deploymentUnit.getAttachment(Attachments.MODULE_IDENTIFIER);

    ResteasyDeploymentData resteasyDeploymentData = new ResteasyDeploymentData();
    final WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
    final Module module = deploymentUnit.getAttachment(Attachments.MODULE);

    try {

      if (warMetaData == null) {
        resteasyDeploymentData.setScanAll(true);
        scan(deploymentUnit, module.getClassLoader(), resteasyDeploymentData);
        deploymentData.put(moduleIdentifier, resteasyDeploymentData);
      } else {
        scanWebDeployment(
            deploymentUnit,
            warMetaData.getMergedJBossWebMetaData(),
            module.getClassLoader(),
            resteasyDeploymentData);
        scan(deploymentUnit, module.getClassLoader(), resteasyDeploymentData);
      }
      deploymentUnit.putAttachment(
          JaxrsAttachments.RESTEASY_DEPLOYMENT_DATA, resteasyDeploymentData);
    } catch (ModuleLoadException e) {
      throw new DeploymentUnitProcessingException(e);
    }
  }
  private void processDeployment(
      final WarMetaData warMetaData,
      final DeploymentUnit deploymentUnit,
      final ServiceTarget serviceTarget,
      String hostName)
      throws DeploymentUnitProcessingException {
    ResourceRoot deploymentResourceRoot = deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT);
    final VirtualFile deploymentRoot = deploymentResourceRoot.getRoot();
    final Module module = deploymentUnit.getAttachment(Attachments.MODULE);
    if (module == null) {
      throw new DeploymentUnitProcessingException(
          UndertowLogger.ROOT_LOGGER.failedToResolveModule(deploymentUnit));
    }
    final JBossWebMetaData metaData = warMetaData.getMergedJBossWebMetaData();
    final List<SetupAction> setupActions =
        deploymentUnit.getAttachmentList(org.jboss.as.ee.component.Attachments.WEB_SETUP_ACTIONS);
    metaData.resolveRunAs();

    ScisMetaData scisMetaData = deploymentUnit.getAttachment(ScisMetaData.ATTACHMENT_KEY);

    final Set<ServiceName> dependentComponents = new HashSet<>();
    // see AS7-2077
    // basically we want to ignore components that have failed for whatever reason
    // if they are important they will be picked up when the web deployment actually starts
    final List<ServiceName> components =
        deploymentUnit.getAttachmentList(WebComponentDescription.WEB_COMPONENTS);
    final Set<ServiceName> failed =
        deploymentUnit.getAttachment(org.jboss.as.ee.component.Attachments.FAILED_COMPONENTS);
    for (final ServiceName component : components) {
      if (!failed.contains(component)) {
        dependentComponents.add(component);
      }
    }

    boolean componentRegistryExists = true;
    ComponentRegistry componentRegistry =
        deploymentUnit.getAttachment(org.jboss.as.ee.component.Attachments.COMPONENT_REGISTRY);
    if (componentRegistry == null) {
      componentRegistryExists = false;
      // we do this to avoid lots of other null checks
      // this will only happen if the EE subsystem is not installed
      componentRegistry = new ComponentRegistry(null);
    }

    final WebInjectionContainer injectionContainer =
        new WebInjectionContainer(module.getClassLoader(), componentRegistry);

    String jaccContextId = metaData.getJaccContextID();

    if (jaccContextId == null) {
      jaccContextId = deploymentUnit.getName();
    }
    if (deploymentUnit.getParent() != null) {
      jaccContextId = deploymentUnit.getParent().getName() + "!" + jaccContextId;
    }

    String deploymentName;
    if (deploymentUnit.getParent() == null) {
      deploymentName = deploymentUnit.getName();
    } else {
      deploymentName = deploymentUnit.getParent().getName() + "." + deploymentUnit.getName();
    }

    final String pathName = pathNameOfDeployment(deploymentUnit, metaData);

    boolean securityEnabled = deploymentUnit.hasAttachment(SecurityAttachments.SECURITY_ENABLED);

    String metaDataSecurityDomain = metaData.getSecurityDomain();
    if (metaDataSecurityDomain == null) {
      metaDataSecurityDomain = getJBossAppSecurityDomain(deploymentUnit);
    }
    if (metaDataSecurityDomain != null) {
      metaDataSecurityDomain = metaDataSecurityDomain.trim();
    }

    final String securityDomain;
    if (securityEnabled) {
      securityDomain =
          metaDataSecurityDomain == null
              ? SecurityConstants.DEFAULT_APPLICATION_POLICY
              : SecurityUtil.unprefixSecurityDomain(metaDataSecurityDomain);
    } else {
      securityDomain = null;
    }

    String serverInstanceName =
        metaData.getServerInstanceName() == null ? defaultServer : metaData.getServerInstanceName();
    final ServiceName deploymentServiceName =
        UndertowService.deploymentServiceName(serverInstanceName, hostName, pathName);

    final Set<ServiceName> additionalDependencies = new HashSet<>();
    for (final SetupAction setupAction : setupActions) {
      Set<ServiceName> dependencies = setupAction.dependencies();
      if (dependencies != null) {
        additionalDependencies.addAll(dependencies);
      }
    }
    SharedSessionManagerConfig sharedSessionManagerConfig =
        deploymentUnit.getParent() != null
            ? deploymentUnit
                .getParent()
                .getAttachment(UndertowAttachments.SHARED_SESSION_MANAGER_CONFIG)
            : null;

    if (!deploymentResourceRoot.isUsePhysicalCodeSource()) {
      try {
        deploymentUnit.addToAttachmentList(
            ServletContextAttribute.ATTACHMENT_KEY,
            new ServletContextAttribute(
                Constants.CODE_SOURCE_ATTRIBUTE_NAME, deploymentRoot.toURL()));
      } catch (MalformedURLException e) {
        throw new DeploymentUnitProcessingException(e);
      }
    }

    deploymentUnit.addToAttachmentList(
        ServletContextAttribute.ATTACHMENT_KEY,
        new ServletContextAttribute(
            Constants.PERMISSION_COLLECTION_ATTRIBUTE_NAME,
            deploymentUnit.getAttachment(Attachments.MODULE_PERMISSIONS)));

    additionalDependencies.addAll(warMetaData.getAdditionalDependencies());

    final ServiceName hostServiceName =
        UndertowService.virtualHostName(serverInstanceName, hostName);
    TldsMetaData tldsMetaData = deploymentUnit.getAttachment(TldsMetaData.ATTACHMENT_KEY);
    UndertowDeploymentInfoService undertowDeploymentInfoService =
        UndertowDeploymentInfoService.builder()
            .setAttributes(deploymentUnit.getAttachmentList(ServletContextAttribute.ATTACHMENT_KEY))
            .setTopLevelDeploymentName(
                deploymentUnit.getParent() == null
                    ? deploymentUnit.getName()
                    : deploymentUnit.getParent().getName())
            .setContextPath(pathName)
            .setDeploymentName(
                deploymentName) // todo: is this deployment name concept really applicable?
            .setDeploymentRoot(deploymentRoot)
            .setMergedMetaData(warMetaData.getMergedJBossWebMetaData())
            .setModule(module)
            .setScisMetaData(scisMetaData)
            .setJaccContextId(jaccContextId)
            .setSecurityDomain(securityDomain)
            .setSharedTlds(
                tldsMetaData == null
                    ? Collections.<TldMetaData>emptyList()
                    : tldsMetaData.getSharedTlds(deploymentUnit))
            .setTldsMetaData(tldsMetaData)
            .setSetupActions(setupActions)
            .setSharedSessionManagerConfig(sharedSessionManagerConfig)
            .setOverlays(warMetaData.getOverlays())
            .setExpressionFactoryWrappers(
                deploymentUnit.getAttachmentList(ExpressionFactoryWrapper.ATTACHMENT_KEY))
            .setPredicatedHandlers(
                deploymentUnit.getAttachment(
                    UndertowHandlersDeploymentProcessor.PREDICATED_HANDLERS))
            .setInitialHandlerChainWrappers(
                deploymentUnit.getAttachmentList(
                    UndertowAttachments.UNDERTOW_INITIAL_HANDLER_CHAIN_WRAPPERS))
            .setInnerHandlerChainWrappers(
                deploymentUnit.getAttachmentList(
                    UndertowAttachments.UNDERTOW_INNER_HANDLER_CHAIN_WRAPPERS))
            .setOuterHandlerChainWrappers(
                deploymentUnit.getAttachmentList(
                    UndertowAttachments.UNDERTOW_OUTER_HANDLER_CHAIN_WRAPPERS))
            .setThreadSetupActions(
                deploymentUnit.getAttachmentList(UndertowAttachments.UNDERTOW_THREAD_SETUP_ACTIONS))
            .setServletExtensions(
                deploymentUnit.getAttachmentList(UndertowAttachments.UNDERTOW_SERVLET_EXTENSIONS))
            .setExplodedDeployment(ExplodedDeploymentMarker.isExplodedDeployment(deploymentUnit))
            .setWebSocketDeploymentInfo(
                deploymentUnit.getAttachment(UndertowAttachments.WEB_SOCKET_DEPLOYMENT_INFO))
            .setTempDir(warMetaData.getTempDir())
            .setExternalResources(
                deploymentUnit.getAttachmentList(UndertowAttachments.EXTERNAL_RESOURCES))
            .createUndertowDeploymentInfoService();

    final ServiceName deploymentInfoServiceName =
        deploymentServiceName.append(UndertowDeploymentInfoService.SERVICE_NAME);
    ServiceBuilder<DeploymentInfo> infoBuilder =
        serviceTarget
            .addService(deploymentInfoServiceName, undertowDeploymentInfoService)
            .addDependency(
                UndertowService.SERVLET_CONTAINER.append(defaultContainer),
                ServletContainerService.class,
                undertowDeploymentInfoService.getContainer())
            .addDependency(
                UndertowService.UNDERTOW,
                UndertowService.class,
                undertowDeploymentInfoService.getUndertowService())
            .addDependencies(deploymentUnit.getAttachmentList(Attachments.WEB_DEPENDENCIES))
            .addDependency(hostServiceName, Host.class, undertowDeploymentInfoService.getHost())
            .addDependency(
                SuspendController.SERVICE_NAME,
                SuspendController.class,
                undertowDeploymentInfoService.getSuspendControllerInjectedValue())
            .addDependencies(additionalDependencies);
    if (securityDomain != null) {
      infoBuilder.addDependency(
          SecurityDomainService.SERVICE_NAME.append(securityDomain),
          SecurityDomainContext.class,
          undertowDeploymentInfoService.getSecurityDomainContextValue());
    }

    if (RequestControllerActivationMarker.isRequestControllerEnabled(deploymentUnit)) {
      String topLevelName;
      if (deploymentUnit.getParent() == null) {
        topLevelName = deploymentUnit.getName();
      } else {
        topLevelName = deploymentUnit.getParent().getName();
      }
      infoBuilder.addDependency(
          ControlPointService.serviceName(topLevelName, UndertowExtension.SUBSYSTEM_NAME),
          ControlPoint.class,
          undertowDeploymentInfoService.getControlPointInjectedValue());
    }
    final Set<String> seenExecutors = new HashSet<String>();
    if (metaData.getExecutorName() != null) {
      final InjectedValue<Executor> executor = new InjectedValue<Executor>();
      infoBuilder.addDependency(
          IOServices.WORKER.append(metaData.getExecutorName()), Executor.class, executor);
      undertowDeploymentInfoService.addInjectedExecutor(metaData.getExecutorName(), executor);
      seenExecutors.add(metaData.getExecutorName());
    }
    if (metaData.getServlets() != null) {
      for (JBossServletMetaData servlet : metaData.getServlets()) {
        if (servlet.getExecutorName() != null
            && !seenExecutors.contains(servlet.getExecutorName())) {
          final InjectedValue<Executor> executor = new InjectedValue<Executor>();
          infoBuilder.addDependency(
              IOServices.WORKER.append(servlet.getExecutorName()), Executor.class, executor);
          undertowDeploymentInfoService.addInjectedExecutor(servlet.getExecutorName(), executor);
          seenExecutors.add(servlet.getExecutorName());
        }
      }
    }

    if (componentRegistryExists) {
      infoBuilder.addDependency(
          ComponentRegistry.serviceName(deploymentUnit),
          ComponentRegistry.class,
          undertowDeploymentInfoService.getComponentRegistryInjectedValue());
    } else {
      undertowDeploymentInfoService
          .getComponentRegistryInjectedValue()
          .setValue(new ImmediateValue<>(componentRegistry));
    }

    if (sharedSessionManagerConfig != null) {
      infoBuilder.addDependency(
          deploymentUnit
              .getParent()
              .getServiceName()
              .append(SharedSessionManagerConfig.SHARED_SESSION_MANAGER_SERVICE_NAME),
          SessionManagerFactory.class,
          undertowDeploymentInfoService.getSessionManagerFactoryInjector());
      infoBuilder.addDependency(
          deploymentUnit
              .getParent()
              .getServiceName()
              .append(SharedSessionManagerConfig.SHARED_SESSION_IDENTIFIER_CODEC_SERVICE_NAME),
          SessionIdentifierCodec.class,
          undertowDeploymentInfoService.getSessionIdentifierCodecInjector());
    } else {
      ServiceName sessionManagerFactoryServiceName =
          installSessionManagerFactory(
              serviceTarget, deploymentServiceName, deploymentName, module, metaData);
      infoBuilder.addDependency(
          sessionManagerFactoryServiceName,
          SessionManagerFactory.class,
          undertowDeploymentInfoService.getSessionManagerFactoryInjector());

      ServiceName sessionIdentifierCodecServiceName =
          installSessionIdentifierCodec(
              serviceTarget, deploymentServiceName, deploymentName, metaData);
      infoBuilder.addDependency(
          sessionIdentifierCodecServiceName,
          SessionIdentifierCodec.class,
          undertowDeploymentInfoService.getSessionIdentifierCodecInjector());
    }

    infoBuilder.install();

    final boolean isWebappBundle = deploymentUnit.hasAttachment(Attachments.OSGI_MANIFEST);

    final UndertowDeploymentService service =
        new UndertowDeploymentService(injectionContainer, !isWebappBundle);
    final ServiceBuilder<UndertowDeploymentService> builder =
        serviceTarget
            .addService(deploymentServiceName, service)
            .addDependencies(dependentComponents)
            .addDependency(
                UndertowService.SERVLET_CONTAINER.append(defaultContainer),
                ServletContainerService.class,
                service.getContainer())
            .addDependency(hostServiceName, Host.class, service.getHost())
            .addDependencies(deploymentUnit.getAttachmentList(Attachments.WEB_DEPENDENCIES))
            .addDependency(
                deploymentInfoServiceName,
                DeploymentInfo.class,
                service.getDeploymentInfoInjectedValue());
    // inject the server executor which can be used by the WebDeploymentService for blocking tasks
    // in start/stop
    // of that service
    Services.addServerExecutorDependency(builder, service.getServerExecutorInjector(), false);

    deploymentUnit.addToAttachmentList(
        Attachments.DEPLOYMENT_COMPLETE_SERVICES, deploymentServiceName);

    // adding JACC service
    if (securityEnabled) {
      AbstractSecurityDeployer<WarMetaData> deployer = new WarJACCDeployer();
      JaccService<WarMetaData> jaccService = deployer.deploy(deploymentUnit, jaccContextId);
      if (jaccService != null) {
        final ServiceName jaccServiceName =
            deploymentUnit.getServiceName().append(JaccService.SERVICE_NAME);
        ServiceBuilder<?> jaccBuilder = serviceTarget.addService(jaccServiceName, jaccService);
        if (deploymentUnit.getParent() != null) {
          // add dependency to parent policy
          final DeploymentUnit parentDU = deploymentUnit.getParent();
          jaccBuilder.addDependency(
              parentDU.getServiceName().append(JaccService.SERVICE_NAME),
              PolicyConfiguration.class,
              jaccService.getParentPolicyInjector());
        }
        // add dependency to web deployment service
        jaccBuilder.addDependency(deploymentServiceName);
        jaccBuilder.setInitialMode(Mode.PASSIVE).install();
      }
    }

    // OSGi web applications are activated in {@link WebContextActivationProcessor} according to
    // bundle lifecycle changes
    if (isWebappBundle) {
      UndertowDeploymentService.ContextActivatorImpl activator =
          new UndertowDeploymentService.ContextActivatorImpl(builder.install());
      deploymentUnit.putAttachment(ContextActivator.ATTACHMENT_KEY, activator);
      deploymentUnit.addToAttachmentList(
          Attachments.BUNDLE_ACTIVE_DEPENDENCIES, deploymentServiceName);
    } else {
      builder.install();
    }

    // Process the web related mgmt information
    final DeploymentResourceSupport deploymentResourceSupport =
        deploymentUnit.getAttachment(Attachments.DEPLOYMENT_RESOURCE_SUPPORT);
    final ModelNode node =
        deploymentResourceSupport.getDeploymentSubsystemModel(UndertowExtension.SUBSYSTEM_NAME);
    node.get(DeploymentDefinition.CONTEXT_ROOT.getName()).set("".equals(pathName) ? "/" : pathName);
    node.get(DeploymentDefinition.VIRTUAL_HOST.getName()).set(hostName);
    node.get(DeploymentDefinition.SERVER.getName()).set(serverInstanceName);
    processManagement(deploymentUnit, metaData);
  }
  @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);
                }
              }
            }
          }
        }
      }
    }
  }
  /** Process SCIs. */
  public void deploy(final DeploymentPhaseContext phaseContext)
      throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    final ModuleSpecification moduleSpecification =
        deploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION);
    final ServiceModuleLoader loader =
        deploymentUnit.getAttachment(Attachments.SERVICE_MODULE_LOADER);
    if (!DeploymentTypeMarker.isType(DeploymentType.WAR, deploymentUnit)) {
      return; // Skip non web deployments
    }
    WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
    assert warMetaData != null;
    final Module module = deploymentUnit.getAttachment(Attachments.MODULE);
    if (module == null) {
      throw MESSAGES.failedToResolveModule(deploymentUnit);
    }
    final ClassLoader classLoader = module.getClassLoader();
    ScisMetaData scisMetaData = deploymentUnit.getAttachment(ScisMetaData.ATTACHMENT_KEY);
    if (scisMetaData == null) {
      scisMetaData = new ScisMetaData();
      deploymentUnit.putAttachment(ScisMetaData.ATTACHMENT_KEY, scisMetaData);
    }
    Set<ServletContainerInitializer> scis = scisMetaData.getScis();
    if (scis == null) {
      scis = new HashSet<ServletContainerInitializer>();
      scisMetaData.setScis(scis);
    }
    Map<ServletContainerInitializer, Set<Class<?>>> handlesTypes = scisMetaData.getHandlesTypes();
    if (handlesTypes == null) {
      handlesTypes = new HashMap<ServletContainerInitializer, Set<Class<?>>>();
      scisMetaData.setHandlesTypes(handlesTypes);
    }
    // Find the SCIs from shared modules
    for (ModuleDependency dependency : moduleSpecification.getSystemDependencies()) {
      try {
        Module depModule = loader.loadModule(dependency.getIdentifier());
        ServiceLoader<ServletContainerInitializer> serviceLoader =
            depModule.loadService(ServletContainerInitializer.class);
        for (ServletContainerInitializer service : serviceLoader) {
          scis.add(service);
        }
      } catch (ModuleLoadException e) {
        if (dependency.isOptional() == false) {
          throw MESSAGES.errorLoadingSCIFromModule(dependency.getIdentifier(), e);
        }
      }
    }
    // Find local ServletContainerInitializer services
    List<String> order = warMetaData.getOrder();
    Map<String, VirtualFile> localScis = warMetaData.getScis();
    if (order != null && localScis != null) {
      for (String jar : order) {
        VirtualFile sci = localScis.get(jar);
        if (sci != null) {
          ServletContainerInitializer service = loadSci(classLoader, sci, jar, true);
          if (service != null) {
            scis.add(service);
          }
        }
      }
    }
    // Process HandlesTypes for ServletContainerInitializer
    Map<Class<?>, Set<ServletContainerInitializer>> typesMap =
        new HashMap<Class<?>, Set<ServletContainerInitializer>>();
    for (ServletContainerInitializer service : scis) {
      if (service.getClass().isAnnotationPresent(HandlesTypes.class)) {
        HandlesTypes handlesTypesAnnotation = service.getClass().getAnnotation(HandlesTypes.class);
        Class<?>[] typesArray = handlesTypesAnnotation.value();
        if (typesArray != null) {
          for (Class<?> type : typesArray) {
            Set<ServletContainerInitializer> servicesSet = typesMap.get(type);
            if (servicesSet == null) {
              servicesSet = new HashSet<ServletContainerInitializer>();
              typesMap.put(type, servicesSet);
            }
            servicesSet.add(service);
            handlesTypes.put(service, new HashSet<Class<?>>());
          }
        }
      }
    }
    Class<?>[] typesArray = typesMap.keySet().toArray(new Class<?>[0]);

    final CompositeIndex index =
        deploymentUnit.getAttachment(Attachments.COMPOSITE_ANNOTATION_INDEX);
    if (index == null) {
      throw MESSAGES.unableToResolveAnnotationIndex(deploymentUnit);
    }

    // Find classes which extend, implement, or are annotated by HandlesTypes
    for (Class<?> type : typesArray) {
      DotName className = DotName.createSimple(type.getName());
      Set<ClassInfo> classInfos = processHandlesType(className, type, index);
      Set<Class<?>> classes = loadClassInfoSet(classInfos, classLoader);
      Set<ServletContainerInitializer> sciSet = typesMap.get(type);
      for (ServletContainerInitializer sci : sciSet) {
        handlesTypes.get(sci).addAll(classes);
      }
    }
  }
  private void processDeployment(
      final WarMetaData warMetaData,
      final DeploymentUnit deploymentUnit,
      final ServiceTarget serviceTarget,
      String hostName)
      throws DeploymentUnitProcessingException {
    final VirtualFile deploymentRoot =
        deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT).getRoot();
    final Module module = deploymentUnit.getAttachment(Attachments.MODULE);
    if (module == null) {
      throw new DeploymentUnitProcessingException(MESSAGES.failedToResolveModule(deploymentUnit));
    }
    final DeploymentClassIndex deploymentClassIndex =
        deploymentUnit.getAttachment(Attachments.CLASS_INDEX);
    final JBossWebMetaData metaData = warMetaData.getMergedJBossWebMetaData();
    final List<SetupAction> setupActions =
        deploymentUnit.getAttachmentList(org.jboss.as.ee.component.Attachments.WEB_SETUP_ACTIONS);

    ScisMetaData scisMetaData = deploymentUnit.getAttachment(ScisMetaData.ATTACHMENT_KEY);

    final Set<ServiceName> dependentComponents = new HashSet<>();
    // see AS7-2077
    // basically we want to ignore components that have failed for whatever reason
    // if they are important they will be picked up when the web deployment actually starts
    final List<ServiceName> components =
        deploymentUnit.getAttachmentList(WebComponentDescription.WEB_COMPONENTS);
    final Set<ServiceName> failed =
        deploymentUnit.getAttachment(org.jboss.as.ee.component.Attachments.FAILED_COMPONENTS);
    for (final ServiceName component : components) {
      boolean skip = false;
      if (!failed.contains(component)) {
        dependentComponents.add(component);
      }
    }

    ComponentRegistry componentRegistry =
        deploymentUnit.getAttachment(org.jboss.as.ee.component.Attachments.COMPONENT_REGISTRY);
    if (componentRegistry == null) {
      // we do this to avoid lots of other null checks
      // this will only happen if the EE subsystem is not installed
      componentRegistry = new ComponentRegistry(null);
    }

    final WebInjectionContainer injectionContainer =
        new WebInjectionContainer(module.getClassLoader(), componentRegistry);

    DeploymentInfo deploymentInfo =
        createServletConfig(
            metaData,
            deploymentUnit,
            module,
            deploymentClassIndex,
            injectionContainer,
            componentRegistry,
            scisMetaData,
            deploymentRoot);

    final String pathName = pathNameOfDeployment(deploymentUnit, metaData);
    deploymentInfo.setContextPath(pathName);

    String metaDataSecurityDomain = metaData.getSecurityDomain();
    if (metaDataSecurityDomain == null) {
      metaDataSecurityDomain = getJBossAppSecurityDomain(deploymentUnit);
    }
    if (metaDataSecurityDomain != null) {
      metaDataSecurityDomain = metaDataSecurityDomain.trim();
    }

    String securityDomain =
        metaDataSecurityDomain == null
            ? SecurityConstants.DEFAULT_APPLICATION_POLICY
            : SecurityUtil.unprefixSecurityDomain(metaDataSecurityDomain);

    final ServiceName deploymentServiceName =
        UndertowService.deploymentServiceName(hostName, deploymentInfo.getContextPath());
    final ServiceName hostServiceName = UndertowService.virtualHostName(defaultServer, hostName);
    final UndertowDeploymentService service =
        new UndertowDeploymentService(
            deploymentInfo, injectionContainer, module, warMetaData.getMergedJBossWebMetaData());
    final ServiceBuilder<UndertowDeploymentService> builder =
        serviceTarget
            .addService(deploymentServiceName, service)
            .addDependencies(dependentComponents)
            .addDependency(
                UndertowService.SERVLET_CONTAINER.append(defaultContainer),
                ServletContainerService.class,
                service.getContainer())
            .addDependency(hostServiceName, Host.class, service.getHost())
            .addDependency(
                SecurityDomainService.SERVICE_NAME.append(securityDomain),
                SecurityDomainContext.class,
                service.getSecurityDomainContextValue())
            .addDependency(
                UndertowService.UNDERTOW, UndertowService.class, service.getUndertowService());

    deploymentUnit.addToAttachmentList(
        Attachments.DEPLOYMENT_COMPLETE_SERVICES, deploymentServiceName);

    // add any dependencies required by the setup action
    for (final SetupAction action : setupActions) {
      builder.addDependencies(action.dependencies());
      deploymentInfo.addThreadSetupAction(
          new ThreadSetupAction() {

            @Override
            public Handle setup(final HttpServerExchange exchange) {
              action.setup(Collections.<String, Object>emptyMap());
              return new Handle() {
                @Override
                public void tearDown() {
                  action.teardown(Collections.<String, Object>emptyMap());
                }
              };
            }
          });
    }

    if (metaData.getDistributable() != null) {
      DistributedCacheManagerFactoryService factoryService =
          new DistributedCacheManagerFactoryService();
      DistributedCacheManagerFactory factory = factoryService.getValue();
      if (factory != null) {
        ServiceName factoryServiceName = deploymentServiceName.append("session");
        builder.addDependency(
            ServiceBuilder.DependencyType.OPTIONAL,
            factoryServiceName,
            DistributedCacheManagerFactory.class,
            service.getDistributedCacheManagerFactoryInjectedValue());

        ServiceBuilder<DistributedCacheManagerFactory> factoryBuilder =
            serviceTarget.addService(factoryServiceName, factoryService);
        boolean enabled =
            factory.addDeploymentDependencies(
                deploymentServiceName,
                deploymentUnit.getServiceRegistry(),
                serviceTarget,
                factoryBuilder,
                metaData);
        factoryBuilder.setInitialMode(enabled ? Mode.ON_DEMAND : Mode.NEVER).install();
      }
    }

    // OSGi web applications are activated in {@link WebContextActivationProcessor} according to
    // bundle lifecycle changes
    if (deploymentUnit.hasAttachment(Attachments.OSGI_MANIFEST)) {
      builder.setInitialMode(Mode.NEVER);
      UndertowDeploymentService.ContextActivatorImpl activator =
          new UndertowDeploymentService.ContextActivatorImpl(builder.install());
      deploymentUnit.putAttachment(ContextActivator.ATTACHMENT_KEY, activator);
    } else {
      builder.setInitialMode(Mode.ACTIVE);
      builder.install();
    }

    // Process the web related mgmt information
    final ModelNode node =
        deploymentUnit.getDeploymentSubsystemModel(UndertowExtension.SUBSYSTEM_NAME);
    node.get(DeploymentDefinition.CONTEXT_ROOT.getName()).set("".equals(pathName) ? "/" : pathName);
    node.get(DeploymentDefinition.VIRTUAL_HOST.getName()).set(hostName);
    processManagement(deploymentUnit, metaData);
  }
  @Override
  public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    SipMetaData sipMetaData = deploymentUnit.getAttachment(SipMetaData.ATTACHMENT_KEY);
    if (sipMetaData == null) {
      SipAnnotationMetaData sipAnnotationMetaData =
          deploymentUnit.getAttachment(SipAnnotationMetaData.ATTACHMENT_KEY);
      if (sipAnnotationMetaData == null
          || !sipAnnotationMetaData.isSipApplicationAnnotationPresent()) {
        // http://code.google.com/p/sipservlets/issues/detail?id=168
        // When no sip.xml but annotations only, Application is not recognized as SIP App by AS7

        // In case there is no metadata attached, it means this is not a sip deployment, so we can
        // safely
        // ignore
        // it!
        return;
      }
    }

    final WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
    final JBossWebMetaData metaData = warMetaData.getMergedJBossWebMetaData();

    // lets find default server service:
    final ServiceName defaultServerServiceName = UndertowService.DEFAULT_SERVER;
    ServiceController<?> defaultServerServiceController =
        phaseContext.getServiceRegistry().getService(defaultServerServiceName);
    Server defaultServerService = (Server) defaultServerServiceController.getValue();

    final String defaultServer = defaultServerService.getName();
    final String defaultHost = defaultServerService.getDefaultHost();

    String hostName = UndertowSipDeploymentProcessor.hostNameOfDeployment(warMetaData, defaultHost);
    final String pathName =
        UndertowSipDeploymentProcessor.pathNameOfDeployment(deploymentUnit, metaData);

    String serverInstanceName =
        metaData.getServerInstanceName() == null ? defaultServer : metaData.getServerInstanceName();

    // lets find udertowdeployment service
    final ServiceName deploymentServiceName =
        UndertowService.deploymentServiceName(serverInstanceName, hostName, pathName);
    ServiceController<?> deploymentServiceController =
        phaseContext.getServiceRegistry().getService(deploymentServiceName);
    UndertowDeploymentService deploymentService =
        (UndertowDeploymentService) deploymentServiceController.getValue();

    // lets find udertowdeploymentinfo service
    final ServiceName deploymentInfoServiceName =
        deploymentServiceName.append(UndertowDeploymentInfoService.SERVICE_NAME);
    ServiceController<?> deploymentInfoServiceController =
        phaseContext.getServiceRegistry().getService(deploymentInfoServiceName);
    UndertowDeploymentInfoService deploymentInfoService =
        (UndertowDeploymentInfoService) deploymentInfoServiceController.getService();

    // lets inject undertowdeployment service to sip deploymentinfo service:
    final ServiceName sipDeploymentInfoServiceName =
        deploymentServiceName.append(UndertowSipDeploymentInfoService.SERVICE_NAME);
    ServiceController<?> sipDeplyomentInfoServiceController =
        phaseContext.getServiceRegistry().getService(sipDeploymentInfoServiceName);
    UndertowSipDeploymentInfoService sipDeplyomentInfoService =
        (UndertowSipDeploymentInfoService) sipDeplyomentInfoServiceController.getService();
    sipDeplyomentInfoService
        .getDeploymentInfoServiceInjectedValue()
        .setValue(new ImmediateValue<UndertowDeploymentInfoService>(deploymentInfoService));

    // initiate undertowsipdeployment service:
    final ServiceName sipDeploymentServiceName =
        deploymentServiceName.append(UndertowSipDeploymentService.SERVICE_NAME);
    UndertowSipDeploymentService sipDeploymentService =
        new UndertowSipDeploymentService(deploymentService, deploymentUnit);
    ServiceBuilder<UndertowSipDeploymentService> sipDeploymentServiceBuilder =
        phaseContext.getServiceTarget().addService(sipDeploymentServiceName, sipDeploymentService);

    // this service depends on the base undertowdeployment service:
    sipDeploymentServiceBuilder.addDependency(deploymentServiceName);
    sipDeploymentServiceBuilder.install();
  }
  @Override
  public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    if (!DeploymentTypeMarker.isType(DeploymentType.WAR, deploymentUnit)) {
      return; // Skip non web deployments
    }
    final ResourceRoot deploymentRoot = deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT);
    final VirtualFile alternateDescriptor =
        deploymentRoot.getAttachment(
            org.jboss.as.ee.structure.Attachments.ALTERNATE_WEB_DEPLOYMENT_DESCRIPTOR);
    // Locate the descriptor
    final VirtualFile webXml;
    if (alternateDescriptor != null) {
      webXml = alternateDescriptor;
    } else {
      webXml = deploymentRoot.getRoot().getChild(WEB_XML);
    }
    final WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
    assert warMetaData != null;
    if (webXml.exists()) {
      InputStream is = null;
      try {
        is = webXml.openStream();
        final XMLInputFactory inputFactory = XMLInputFactory.newInstance();

        MetaDataElementParser.DTDInfo dtdInfo = new MetaDataElementParser.DTDInfo();
        inputFactory.setXMLResolver(dtdInfo);
        final XMLStreamReader xmlReader = inputFactory.createXMLStreamReader(is);

        WebMetaData webMetaData =
            WebMetaDataParser.parse(
                xmlReader,
                dtdInfo,
                SpecDescriptorPropertyReplacement.propertyReplacer(deploymentUnit));

        if (schemaValidation && webMetaData.getSchemaLocation() != null) {
          XMLSchemaValidator validator = new XMLSchemaValidator(new XMLResourceResolver());
          InputStream xmlInput = webXml.openStream();
          try {
            if (webMetaData.is23())
              validator.validate(
                  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN", xmlInput);
            else if (webMetaData.is24())
              validator.validate("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd", xmlInput);
            else if (webMetaData.is25())
              validator.validate("http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd", xmlInput);
            else if (webMetaData.is30())
              validator.validate("http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd", xmlInput);
            else if (webMetaData.is31())
              validator.validate("http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd", xmlInput);
            else
              validator.validate(
                  "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN", xmlInput);
          } catch (SAXException e) {
            throw new DeploymentUnitProcessingException("Failed to validate " + webXml, e);
          } finally {
            xmlInput.close();
          }
        }
        warMetaData.setWebMetaData(webMetaData);

      } catch (XMLStreamException e) {
        throw new DeploymentUnitProcessingException(
            MESSAGES.failToParseXMLDescriptor(
                webXml, e.getLocation().getLineNumber(), e.getLocation().getColumnNumber()));
      } catch (IOException e) {
        throw new DeploymentUnitProcessingException(MESSAGES.failToParseXMLDescriptor(webXml), e);
      } finally {
        try {
          if (is != null) {
            is.close();
          }
        } catch (IOException e) {
          // Ignore
        }
      }
    }
  }