@Override
  public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
    DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();

    if (deploymentUnit.hasAttachment(ClojureMetaData.ATTACHMENT_KEY)) {
      return;
    }

    Timer t = new Timer("parsing deployment descriptor");
    String deploymentName = deploymentUnit.getName();

    try {
      VirtualFile descriptor = getDescriptorFile(deploymentUnit);
      if (descriptor == null) {
        return;
      }

      ClojureMetaData appMetaData =
          new ClojureMetaData(deploymentName, ClojureMetaData.parse(descriptor.getPhysicalFile()));

      appMetaData.attachTo(deploymentUnit);

      File root = appMetaData.getRoot();

      if (root == null) {
        throw new DeploymentUnitProcessingException("No application root specified.");
      }

      if (!root.exists()) {
        throw new DeploymentUnitProcessingException(
            "Application root does not exist: " + root.getAbsolutePath());
      }

      VirtualFile virtualRoot = VFS.getChild(root.toURI());
      MountHandle mountHandle = null;

      if (!root.isDirectory()) {
        // Expand the referenced root if it's not a directory (ie .ima archive)
        mountHandle =
            new MountHandle(
                VFS.mountZipExpanded(virtualRoot, virtualRoot, TempFileProviderService.provider()));
      }

      deploymentUnit.putAttachment(
          Attachments.DEPLOYMENT_ROOT, new ResourceRoot(virtualRoot, mountHandle));
      deploymentUnit.putAttachment(ClojureMetaData.DESCRIPTOR_FILE, descriptor.getPhysicalFile());

    } catch (Exception e) {
      throw new DeploymentUnitProcessingException(e);
    }
    t.done();
  }
  @Override
  public void updateResource(
      final String archiveName, final Map<String, byte[]> replacedResources) {
    final ModuleIdentifier moduleId = getModuleIdentifier(archiveName);
    final ModuleClassLoader loader = loadersByModuleIdentifier.get(moduleId);
    if (loader == null) {
      return;
    }

    final DeploymentUnit deploymentUnit =
        (DeploymentUnit)
            CurrentServiceRegistry.getServiceRegistry()
                .getRequiredService(Services.deploymentUnitName(archiveName))
                .getValue();
    final ResourceRoot root = deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT);

    for (final Map.Entry<String, byte[]> entry : replacedResources.entrySet()) {
      final VirtualFile file = root.getRoot().getChild(entry.getKey());
      try {
        final FileOutputStream stream = new FileOutputStream(file.getPhysicalFile(), false);
        try {
          stream.write(entry.getValue());
        } finally {
          stream.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
 @Override
 public Closeable mountDeploymentContent(
     final VirtualFile contents, VirtualFile mountPoint, MountType type) throws IOException {
   // according to the javadoc contents can not be null
   assert contents != null : "null contents";
   switch (type) {
     case ZIP:
       return VFS.mountZip(contents, mountPoint, tempFileProvider);
     case EXPANDED:
       return VFS.mountZipExpanded(contents, mountPoint, tempFileProvider);
     case REAL:
       return VFS.mountReal(contents.getPhysicalFile(), mountPoint);
     default:
       throw ServerMessages.MESSAGES.unknownMountType(type);
   }
 }
 public ModuleIdentifier addExternalModule(VirtualFile externalModule) {
   ModuleIdentifier identifier =
       ModuleIdentifier.create(EXTERNAL_MODULE_PREFIX + externalModule.getPathName());
   ServiceName serviceName = ServiceModuleLoader.moduleSpecServiceName(identifier);
   ServiceController<?> controller = serviceContainer.getService(serviceName);
   if (controller == null) {
     try {
       ExternalModuleSpecService service =
           new ExternalModuleSpecService(identifier, externalModule.getPhysicalFile());
       serviceContainer.addService(serviceName, service).setInitialMode(Mode.ON_DEMAND).install();
     } catch (IOException e) {
       throw new RuntimeException(e);
     }
   }
   return identifier;
 }
  /**
   * Process a deployment for standard ra deployment files. Will parse the xml file and attach an
   * configuration discovered during processing.
   *
   * @param phaseContext the deployment unit context
   * @throws DeploymentUnitProcessingException
   */
  @Override
  public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
    final VirtualFile deploymentRoot =
        phaseContext.getDeploymentUnit().getAttachment(Attachments.DEPLOYMENT_ROOT).getRoot();

    if (deploymentRoot == null || !deploymentRoot.exists()) return;

    final String deploymentRootName = deploymentRoot.getLowerCaseName();
    if (!deploymentRootName.endsWith(".rar")) {
      return;
    }

    VirtualFile serviceXmlFile = deploymentRoot.getChild("/META-INF/ra.xml");

    InputStream xmlStream = null;
    Connector result = null;
    try {
      if (serviceXmlFile != null && serviceXmlFile.exists()) {

        xmlStream = serviceXmlFile.openStream();
        result = (new RaParser()).parse(xmlStream);
        if (result == null) throw MESSAGES.failedToParseServiceXml(serviceXmlFile);
      }
      File root = deploymentRoot.getPhysicalFile();
      URL url = root.toURI().toURL();
      String deploymentName = deploymentRootName.substring(0, deploymentRootName.indexOf(".rar"));
      ConnectorXmlDescriptor xmlDescriptor =
          new ConnectorXmlDescriptor(result, root, url, deploymentName);
      phaseContext
          .getDeploymentUnit()
          .putAttachment(ConnectorXmlDescriptor.ATTACHMENT_KEY, xmlDescriptor);

    } catch (Exception e) {
      throw MESSAGES.failedToParseServiceXml(e, serviceXmlFile);
    } finally {
      VFSUtils.safeClose(xmlStream);
    }
  }
  protected void processDeployment(
      final String hostName, final WarMetaData warMetaData, final DeploymentUnitContext context)
      throws DeploymentUnitProcessingException {
    final VirtualFile deploymentRoot = VirtualFileAttachment.getVirtualFileAttachment(context);
    final Module module = context.getAttachment(ModuleDeploymentProcessor.MODULE_ATTACHMENT_KEY);
    if (module == null) {
      throw new DeploymentUnitProcessingException(
          "failed to resolve module for deployment " + deploymentRoot);
    }
    final ClassLoader classLoader = module.getClassLoader();
    final JBossWebMetaData metaData = warMetaData.getMergedJBossWebMetaData();

    // Create the context
    final StandardContext webContext = new StandardContext();
    final ContextConfig config = new JBossContextConfig(context);
    // Set the deployment root
    try {
      webContext.setDocBase(deploymentRoot.getPhysicalFile().getAbsolutePath());
    } catch (IOException e) {
      throw new DeploymentUnitProcessingException(e);
    }
    webContext.addLifecycleListener(config);

    // Set the path name
    final String deploymentName = context.getName();
    String pathName = null;
    if (metaData.getContextRoot() == null) {
      pathName = deploymentRoot.getName();
      if (pathName.equals("ROOT.war")) {
        pathName = "";
      } else {
        pathName = "/" + pathName.substring(0, pathName.length() - 4);
      }
    } else {
      pathName = metaData.getContextRoot();
      if ("/".equals(pathName)) {
        pathName = "";
      }
    }
    webContext.setPath(pathName);
    webContext.setIgnoreAnnotations(true);

    // Add a dummy realm for now
    Realm realm = new MemoryRealm();
    webContext.setRealm(realm);

    //
    final Loader loader = new WebCtxLoader(classLoader);
    final InstanceManager manager = new WebInjectionContainer(classLoader);
    webContext.setInstanceManager(manager);
    webContext.setLoader(loader);

    // Set the session cookies flag according to metadata
    switch (metaData.getSessionCookies()) {
      case JBossWebMetaData.SESSION_COOKIES_ENABLED:
        webContext.setCookies(true);
        break;
      case JBossWebMetaData.SESSION_COOKIES_DISABLED:
        webContext.setCookies(false);
        break;
    }

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

    // Add the context service
    final BatchBuilder builder = context.getBatchBuilder();
    builder
        .addService(
            WebSubsystemElement.JBOSS_WEB.append(deploymentName),
            new WebDeploymentService(webContext))
        .addDependency(
            WebSubsystemElement.JBOSS_WEB_HOST.append(hostName),
            Host.class,
            new WebContextInjector(webContext))
        .setInitialMode(Mode.ACTIVE);
  }
  protected void processDeployment(
      final String hostName,
      final WarMetaData warMetaData,
      final DeploymentUnit deploymentUnit,
      final ServiceTarget serviceTarget)
      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(deploymentRoot));
    }
    final ClassLoader classLoader = module.getClassLoader();
    final JBossWebMetaData metaData = warMetaData.getMergedJBossWebMetaData();
    final List<SetupAction> setupActions =
        deploymentUnit.getAttachmentList(org.jboss.as.ee.component.Attachments.WEB_SETUP_ACTIONS);

    // Create the context
    final StandardContext webContext = new StandardContext();
    final JBossContextConfig config = new JBossContextConfig(deploymentUnit);

    // Add SecurityAssociationValve right at the beginning
    webContext.addValve(new SecurityContextAssociationValve(deploymentUnit));

    // Set the deployment root
    try {
      webContext.setDocBase(deploymentRoot.getPhysicalFile().getAbsolutePath());
    } catch (IOException e) {
      throw new DeploymentUnitProcessingException(e);
    }
    webContext.addLifecycleListener(config);

    final String pathName = pathNameOfDeployment(deploymentUnit, metaData);
    webContext.setPath(pathName);
    webContext.setIgnoreAnnotations(true);
    webContext.setCrossContext(!metaData.isDisableCrossContext());

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

    // 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 Map<String, ComponentInstantiator> components =
        deploymentUnit.getAttachment(WebAttachments.WEB_COMPONENT_INSTANTIATORS);
    if (components != null) {
      final Set<ServiceName> failed =
          deploymentUnit.getAttachment(org.jboss.as.ee.component.Attachments.FAILED_COMPONENTS);
      for (Map.Entry<String, ComponentInstantiator> entry : components.entrySet()) {
        boolean skip = false;
        for (final ServiceName serviceName : entry.getValue().getServiceNames()) {
          if (failed.contains(serviceName)) {
            skip = true;
            break;
          }
        }
        if (!skip) {
          injectionContainer.addInstantiator(entry.getKey(), entry.getValue());
        }
      }
    }

    final Loader loader = new WebCtxLoader(classLoader);
    webContext.setLoader(loader);

    // Valves
    List<ValveMetaData> valves = metaData.getValves();
    if (valves == null) {
      metaData.setValves(valves = new ArrayList<ValveMetaData>());
    }
    for (ValveMetaData valve : valves) {
      Valve valveInstance =
          (Valve) getInstance(module, valve.getModule(), valve.getValveClass(), valve.getParams());
      webContext.getPipeline().addValve(valveInstance);
    }

    // Container listeners
    List<ContainerListenerMetaData> listeners = metaData.getContainerListeners();
    if (listeners != null) {
      for (ContainerListenerMetaData listener : listeners) {
        switch (listener.getListenerType()) {
          case CONTAINER:
            ContainerListener containerListener =
                (ContainerListener)
                    getInstance(
                        module,
                        listener.getModule(),
                        listener.getListenerClass(),
                        listener.getParams());
            webContext.addContainerListener(containerListener);
            break;
          case LIFECYCLE:
            LifecycleListener lifecycleListener =
                (LifecycleListener)
                    getInstance(
                        module,
                        listener.getModule(),
                        listener.getListenerClass(),
                        listener.getParams());
            if (webContext instanceof Lifecycle) {
              ((Lifecycle) webContext).addLifecycleListener(lifecycleListener);
            }
            break;
          case SERVLET_INSTANCE:
            webContext.addInstanceListener(listener.getListenerClass());
            break;
          case SERVLET_CONTAINER:
            webContext.addWrapperListener(listener.getListenerClass());
            break;
          case SERVLET_LIFECYCLE:
            webContext.addWrapperLifecycle(listener.getListenerClass());
            break;
        }
      }
    }

    // Set the session cookies flag according to metadata
    switch (metaData.getSessionCookies()) {
      case JBossWebMetaData.SESSION_COOKIES_ENABLED:
        webContext.setCookies(true);
        break;
      case JBossWebMetaData.SESSION_COOKIES_DISABLED:
        webContext.setCookies(false);
        break;
    }

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

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

    // Setup an deployer configured ServletContext attributes
    final List<ServletContextAttribute> attributes =
        deploymentUnit.getAttachment(ServletContextAttribute.ATTACHMENT_KEY);

    try {
      final ServiceName deploymentServiceName =
          WebSubsystemServices.deploymentServiceName(hostName, pathName);
      final ServiceName realmServiceName = deploymentServiceName.append("realm");

      final JBossWebRealmService realmService = new JBossWebRealmService(deploymentUnit);
      ServiceBuilder<?> builder = serviceTarget.addService(realmServiceName, realmService);
      builder
          .addDependency(
              DependencyType.REQUIRED,
              SecurityDomainService.SERVICE_NAME.append(securityDomain),
              SecurityDomainContext.class,
              realmService.getSecurityDomainContextInjector())
          .setInitialMode(Mode.ACTIVE)
          .install();

      final WebDeploymentService webDeploymentService =
          new WebDeploymentService(webContext, injectionContainer, setupActions, attributes);
      builder =
          serviceTarget
              .addService(deploymentServiceName, webDeploymentService)
              .addDependency(
                  WebSubsystemServices.JBOSS_WEB_HOST.append(hostName),
                  VirtualHost.class,
                  new WebContextInjector(webContext))
              .addDependencies(injectionContainer.getServiceNames())
              .addDependency(realmServiceName, Realm.class, webDeploymentService.getRealm())
              .addDependencies(deploymentUnit.getAttachmentList(Attachments.WEB_DEPENDENCIES))
              .addDependency(JndiNamingDependencyProcessor.serviceName(deploymentUnit));

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

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

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

      builder.install();

      // adding JACC service
      AbstractSecurityDeployer<?> deployer = new WarSecurityDeployer();
      JaccService<?> service = deployer.deploy(deploymentUnit);
      if (service != null) {
        ((WarJaccService) service).setContext(webContext);
        final ServiceName jaccServiceName =
            JaccService.SERVICE_NAME.append(deploymentUnit.getName());
        builder = serviceTarget.addService(jaccServiceName, service);
        if (deploymentUnit.getParent() != null) {
          // add dependency to parent policy
          final DeploymentUnit parentDU = deploymentUnit.getParent();
          builder.addDependency(
              JaccService.SERVICE_NAME.append(parentDU.getName()),
              PolicyConfiguration.class,
              service.getParentPolicyInjector());
        }
        // add dependency to web deployment service
        builder.addDependency(deploymentServiceName);
        builder.setInitialMode(Mode.ACTIVE).install();
      }
    } catch (ServiceRegistryException e) {
      throw new DeploymentUnitProcessingException(MESSAGES.failedToAddWebDeployment(), e);
    }

    // Process the web related mgmt information
    final ModelNode node = deploymentUnit.getDeploymentSubsystemModel("web");
    node.get("context-root").set("".equals(pathName) ? "/" : pathName);
    node.get("virtual-host").set(hostName);
    processManagement(deploymentUnit, metaData);
  }